1 # Copyright 2014 The Chromium Authors. All rights reserved.
2 # Use of this source code is governed by a BSD-style license that can be
3 # found in the LICENSE file.
5 from telemetry
.value
import scalar
7 from metrics
import memory
8 from metrics
import Metric
11 class SystemMemoryMetric(Metric
):
12 """SystemMemoryMetric gathers system memory statistic.
14 This metric collects system memory stats per test. It reports the difference
15 (delta) in system memory starts from the start of the test to the end of it.
18 def __init__(self
, browser
):
19 super(SystemMemoryMetric
, self
).__init
__()
20 self
._browser
= browser
21 self
._memory
_stats
_start
= None
22 self
._memory
_stats
_end
= None
24 def Start(self
, page
, tab
):
25 """Start the per-page preparation for this metric.
27 Records the system memory stats at this point.
29 self
._memory
_stats
_start
= self
._browser
.memory_stats
31 def Stop(self
, page
, tab
):
32 """Prepare the results for this page.
34 The results are the differences between the current system memory stats
35 and the values when Start() was called.
37 assert self
._memory
_stats
_start
, 'Must call Start() first'
38 self
._memory
_stats
_end
= self
._browser
.memory_stats
40 # |trace_name| and |exclude_metrics| args are not in base class Metric.
41 # pylint: disable=W0221
42 def AddResults(self
, tab
, results
, trace_name
=None, exclude_metrics
=None):
43 """Add results for this page to the results object.
45 Reports the delta in memory stats between the start stats and the end stats
46 (as *_delta metrics). It reports end memory stats in case no matching start
50 trace_name: Trace name to identify the summary results for current page.
51 exclude_metrics: List of memory metrics to exclude from results,
52 e.g. VM, VMPeak, etc. See AddResultsForProcesses().
54 assert self
._memory
_stats
_end
, 'Must call Stop() first'
55 memory_stats
= _SubtractMemoryStats(self
._memory
_stats
_end
,
56 self
._memory
_stats
_start
)
57 if not memory_stats
['Browser']:
59 exclude_metrics
= exclude_metrics
or {}
60 memory
.AddResultsForProcesses(results
, memory_stats
,
61 metric_trace_name
=trace_name
, chart_trace_name
='delta',
62 exclude_metrics
=exclude_metrics
)
64 if 'SystemCommitCharge' not in exclude_metrics
:
65 results
.AddValue(scalar
.ScalarValue(
67 'commit_charge_delta.%s' % (trace_name
or 'commit_charge'), 'kb',
68 memory_stats
['SystemCommitCharge'], important
=False))
70 if 'ProcessCount' not in exclude_metrics
:
71 results
.AddValue(scalar
.ScalarValue(
73 'processes_delta.%s' % (trace_name
or 'processes'), 'count',
74 memory_stats
['ProcessCount'], important
=False))
77 def _SubtractMemoryStats(end_memory_stats
, start_memory_stats
):
78 """Computes the difference in memory usage stats.
80 Each of the two stats arguments is a dict with the following format:
81 {'Browser': {metric: value, ...},
82 'Renderer': {metric: value, ...},
83 'Gpu': {metric: value, ...},
84 'ProcessCount': value,
87 The metrics can be VM, WorkingSetSize, ProportionalSetSize, etc depending on
90 NOTE: The only metrics that are not subtracted from original are the *Peak*
94 A dict of process type names (Browser, Renderer, etc.) to memory usage
95 metrics between the end collected stats and the start collected stats.
98 end_memory_stats
= end_memory_stats
or {}
99 start_memory_stats
= start_memory_stats
or {}
101 for process_type
in end_memory_stats
:
102 memory_stats
[process_type
] = {}
103 end_process_memory
= end_memory_stats
[process_type
]
104 if not end_process_memory
:
107 # If a process has end stats without start stats then report the end stats.
108 # For example, a GPU process that started just after media playback.
109 if (process_type
not in start_memory_stats
or
110 not start_memory_stats
[process_type
]):
111 memory_stats
[process_type
] = end_process_memory
114 if not isinstance(end_process_memory
, dict):
115 start_value
= start_memory_stats
[process_type
] or 0
116 memory_stats
[process_type
] = end_process_memory
- start_value
118 for metric
in end_process_memory
:
119 end_value
= end_process_memory
[metric
]
120 start_value
= start_memory_stats
[process_type
].get(metric
, 0)
122 memory_stats
[process_type
][metric
] = end_value
124 memory_stats
[process_type
][metric
] = end_value
- start_value