def testGetMemoryUsageWithAndroidMemtrack(self):
     GL1, EGL1, GL2, EGL2 = [2**x for x in range(4)]
     process_dump1 = TestProcessDumpEvent(
         allocators={
             'gpu/android_memtrack/gl': {
                 'memtrack_pss': GL1
             },
             'gpu/android_memtrack/graphics': {
                 'memtrack_pss': EGL1
             }
         })
     process_dump2 = TestProcessDumpEvent(
         allocators={
             'gpu/android_memtrack/gl': {
                 'memtrack_pss': GL2
             },
             'gpu/android_memtrack/graphics': {
                 'memtrack_pss': EGL2
             }
         })
     memory_dump = memory_dump_event.GlobalMemoryDump(
         [process_dump1, process_dump2])
     self.assertEquals(
         {
             'android_memtrack_gl': GL1 + GL2,
             'android_memtrack_graphics': EGL1 + EGL2
         }, memory_dump.GetMemoryUsage())
    def testGetMemoryUsageDiscountsTracing(self):
        ALL = [2**x for x in range(5)]
        (HEAP, DIRTY, MALLOC, TRACING_1, TRACING_2) = ALL

        memory_dump = memory_dump_event.GlobalMemoryDump([
            TestProcessDumpEvent(mmaps={
                '/dev/ashmem/libc malloc': {
                    'pss': HEAP + TRACING_2,
                    'pd': DIRTY + TRACING_2
                }
            },
                                 allocators={
                                     'tracing': {
                                         'size': TRACING_1,
                                         'resident_size': TRACING_2
                                     },
                                     'malloc': {
                                         'size': MALLOC + TRACING_1
                                     }
                                 })
        ])

        self.assertEquals(
            {
                'mmaps_overall_pss': HEAP,
                'mmaps_private_dirty': DIRTY,
                'mmaps_java_heap': 0,
                'mmaps_ashmem': 0,
                'mmaps_native_heap': HEAP,
                'allocator_tracing': TRACING_1,
                'allocator_malloc': MALLOC
            }, memory_dump.GetMemoryUsage())
 def testGetMemoryUsageWithAllocators(self):
     process_dump1 = TestProcessDumpEvent(
         mmaps={'/dev/ashmem/other-ashmem': {
             'pss': 5
         }},
         allocators={'v8': {
             'size': 10,
             'allocated_objects_size': 5
         }})
     process_dump2 = TestProcessDumpEvent(
         mmaps={'/dev/ashmem/other-ashmem': {
             'pss': 5
         }},
         allocators={'v8': {
             'size': 20,
             'allocated_objects_size': 10
         }})
     memory_dump = memory_dump_event.GlobalMemoryDump(
         [process_dump1, process_dump2])
     self.assertEquals(
         {
             'mmaps_overall_pss': 10,
             'mmaps_private_dirty': 0,
             'mmaps_java_heap': 0,
             'mmaps_ashmem': 10,
             'mmaps_native_heap': 0,
             'allocator_v8': 30,
             'allocated_objects_v8': 15
         }, memory_dump.GetMemoryUsage())
Esempio n. 4
0
    def testDumpEventsTiming(self):
        process = mock.Mock()
        process.pid = 1
        composable_dump = memory_dump_event.ProcessMemoryDumpEvent(
            process, [
                MakeRawMemoryDumpEvent(pid=process.pid, start=8),
                MakeRawMemoryDumpEvent(pid=process.pid, start=16),
                MakeRawMemoryDumpEvent(pid=process.pid, start=10)
            ])
        self.assertAlmostEquals(8.0, composable_dump.start)
        self.assertAlmostEquals(16.0, composable_dump.end)

        memory_dump = memory_dump_event.GlobalMemoryDump([
            composable_dump,
            TestProcessDumpEvent(pid=3, start=8),
            TestProcessDumpEvent(pid=2, start=13),
            TestProcessDumpEvent(pid=4, start=7)
        ])

        self.assertFalse(memory_dump.has_mmaps)
        self.assertEquals(4, len(list(memory_dump.IterProcessMemoryDumps())))
        self.assertItemsEqual([1, 2, 3, 4], memory_dump.pids)
        self.assertAlmostEquals(7.0, memory_dump.start)
        self.assertAlmostEquals(16.0, memory_dump.end)
        self.assertAlmostEquals(9.0, memory_dump.duration)
Esempio n. 5
0
def MockTimelineModel(process_dumps):
  dumps_by_id = collections.defaultdict(list)
  for process_dump in process_dumps:
    dumps_by_id[process_dump.dump_id].append(process_dump)

  global_dumps = sorted((memory_dump_event.GlobalMemoryDump(dumps)
                         for dumps in dumps_by_id.itervalues()),
                        key=lambda dump: dump.start)

  mock_model = mock.Mock()
  mock_model.IterGlobalMemoryDumps = mock.Mock(return_value=global_dumps)
  return mock_model
    def testDumpEventsTiming(self):
        memory_dump = memory_dump_event.GlobalMemoryDump([
            TestProcessDumpEvent(pid=3, start=8),
            TestProcessDumpEvent(pid=1, start=4),
            TestProcessDumpEvent(pid=2, start=13),
            TestProcessDumpEvent(pid=4, start=7)
        ])

        self.assertFalse(memory_dump.has_mmaps)
        self.assertEquals(4, len(list(memory_dump.IterProcessMemoryDumps())))
        self.assertAlmostEquals(4.0, memory_dump.start)
        self.assertAlmostEquals(13.0, memory_dump.end)
        self.assertAlmostEquals(9.0, memory_dump.duration)
    def testRepr(self):
        process_dump1 = TestProcessDumpEvent(
            mmaps={'/dev/ashmem/other-ashmem': {
                'pss': 5
            }},
            allocators={'v8': {
                'size': 10,
                'allocated_objects_size': 5
            }})
        process_dump2 = TestProcessDumpEvent(
            mmaps={'/dev/ashmem/libc malloc': {
                'pss': 42,
                'pd': 27
            }},
            allocators={
                'v8': {
                    'size': 20,
                    'allocated_objects_size': 10
                },
                'oilpan': {
                    'size': 40
                }
            })
        global_dump = memory_dump_event.GlobalMemoryDump(
            [process_dump1, process_dump2])

        self.assertEquals(
            repr(process_dump1),
            'ProcessMemoryDumpEvent[pid=1234, allocated_objects_v8=5,'
            ' allocator_v8=10, mmaps_ashmem=5, mmaps_java_heap=0,'
            ' mmaps_native_heap=0, mmaps_overall_pss=5, mmaps_private_dirty=0]'
        )
        self.assertEquals(
            repr(process_dump2),
            'ProcessMemoryDumpEvent[pid=1234, allocated_objects_v8=10,'
            ' allocator_oilpan=40, allocator_v8=20, mmaps_ashmem=0,'
            ' mmaps_java_heap=0, mmaps_native_heap=42, mmaps_overall_pss=42,'
            ' mmaps_private_dirty=27]')
        self.assertEquals(
            repr(global_dump),
            'GlobalMemoryDump[id=123456ABCDEF, allocated_objects_v8=15,'
            ' allocator_oilpan=40, allocator_v8=30, mmaps_ashmem=5,'
            ' mmaps_java_heap=0, mmaps_native_heap=42, mmaps_overall_pss=47,'
            ' mmaps_private_dirty=27]')
Esempio n. 8
0
    def testGetMemoryUsage(self):
        ALL = [2**x for x in range(7)]
        (JAVA_HEAP_1, JAVA_HEAP_2, ASHMEM_1, ASHMEM_2, NATIVE, DIRTY_1,
         DIRTY_2) = ALL

        memory_dump = memory_dump_event.GlobalMemoryDump([
            TestProcessDumpEvent(
                pid=1,
                mmaps={'/dev/ashmem/dalvik-alloc space': {
                    'pss': JAVA_HEAP_1
                }}),
            TestProcessDumpEvent(pid=2,
                                 mmaps={
                                     '/dev/ashmem/other-ashmem': {
                                         'pss': ASHMEM_1,
                                         'pd': DIRTY_1
                                     }
                                 }),
            TestProcessDumpEvent(pid=3,
                                 mmaps={
                                     '[heap] native': {
                                         'pss': NATIVE,
                                         'pd': DIRTY_2
                                     },
                                     '/dev/ashmem/dalvik-zygote space': {
                                         'pss': JAVA_HEAP_2
                                     }
                                 }),
            TestProcessDumpEvent(
                pid=4, mmaps={'/dev/ashmem/other-ashmem': {
                    'pss': ASHMEM_2
                }})
        ])

        self.assertTrue(memory_dump.has_mmaps)
        self.assertItemsEqual([1, 2, 3, 4], memory_dump.pids)
        self.assertEquals(
            {
                'mmaps_overall_pss': sum(ALL[:5]),
                'mmaps_private_dirty': DIRTY_1 + DIRTY_2,
                'mmaps_java_heap': JAVA_HEAP_1 + JAVA_HEAP_2,
                'mmaps_ashmem': ASHMEM_1 + ASHMEM_2,
                'mmaps_native_heap': NATIVE
            }, memory_dump.GetMemoryUsage())
Esempio n. 9
0
 def _CreateMemoryDumps(self):
     self._model.SetGlobalMemoryDumps(
         memory_dump_event.GlobalMemoryDump(events)
         for events in self._all_memory_dumps_by_dump_id.itervalues())
Esempio n. 10
0
    def AddResults(self, model, renderer_thread, interactions, results):
        # Note: This method will be called by TimelineBasedMeasurement once for
        # each thread x interaction_label combination; where |interactions| is
        # a list of all interactions sharing the same label that occurred in the
        # given |renderer_thread|.

        def ContainedIn(dump, interaction):
            return interaction.start < dump.start and dump.end < interaction.end

        def OccursDuringInteractions(dump):
            return (
                # Dump must contain the rendrerer process that requested it,
                renderer_thread.parent.pid in dump.pids and
                # ... and fall within the span of an interaction record.
                any(
                    ContainedIn(dump, interaction)
                    for interaction in interactions))

        def ReportResultsForProcess(memory_dumps, process_name):
            if not memory_dumps:
                metric_values = dict.fromkeys(DEFAULT_METRICS)
                num_processes = None
                none_reason = 'No memory dumps with mmaps found within interactions'
            else:
                metric_values = collections.defaultdict(list)
                num_processes = []
                for dump in memory_dumps:
                    for metric, value in dump.GetMemoryUsage().iteritems():
                        metric_values[metric].append(value)
                    num_processes.append(dump.CountProcessMemoryDumps())
                none_reason = None
            for metric, values in metric_values.iteritems():
                results.AddValue(
                    list_of_scalar_values.ListOfScalarValues(
                        page=results.current_page,
                        name='memory_%s_%s' % (metric, process_name),
                        units='bytes',
                        tir_label=interactions[0].label,
                        values=values,
                        none_value_reason=none_reason,
                        improvement_direction=improvement_direction.DOWN))
            results.AddValue(
                list_of_scalar_values.ListOfScalarValues(
                    page=results.current_page,
                    name='process_count_%s' % process_name,
                    units='count',
                    tir_label=interactions[0].label,
                    values=num_processes,
                    none_value_reason=none_reason,
                    improvement_direction=improvement_direction.DOWN))

        memory_dumps = filter(OccursDuringInteractions,
                              model.IterGlobalMemoryDumps())

        # Either all dumps should contain memory maps (Android, Linux), or none
        # of them (Windows, Mac).
        assert len(set(dump.has_mmaps for dump in memory_dumps)) <= 1

        ReportResultsForProcess(memory_dumps, 'total')

        memory_dumps_by_process_name = collections.defaultdict(list)
        for memory_dump in memory_dumps:
            # Split this global memory_dump into individual process dumps, and then
            # group them by their process names.
            process_dumps_by_name = collections.defaultdict(list)
            for process_dump in memory_dump.IterProcessMemoryDumps():
                process_name = process_dump.process_name.lower().replace(
                    ' ', '_')
                process_dumps_by_name[process_name].append(process_dump)

            # Merge process dumps that have the same process name into a new
            # global dump. Note: this is slightly abusing GlobalMemoryDump so that
            # we can say dump.GetMemoryUsage() on the created dump objects to obtain
            # the memory usage aggregated per type. This should no longer be needed
            # after moving to TBMv2. See: http://crbug.com/581716
            for process_name, process_dumps in process_dumps_by_name.iteritems(
            ):
                memory_dumps_by_process_name[process_name].append(
                    memory_dump_event.GlobalMemoryDump(process_dumps))

        for process_name, memory_dumps in memory_dumps_by_process_name.iteritems(
        ):
            ReportResultsForProcess(memory_dumps, process_name)