OLD | NEW |
1 <!DOCTYPE html> | 1 <!DOCTYPE html> |
2 <!-- | 2 <!-- |
3 Copyright 2016 The Chromium Authors. All rights reserved. | 3 Copyright 2016 The Chromium Authors. All rights reserved. |
4 Use of this source code is governed by a BSD-style license that can be | 4 Use of this source code is governed by a BSD-style license that can be |
5 found in the LICENSE file. | 5 found in the LICENSE file. |
6 --> | 6 --> |
7 | 7 |
8 <link rel="import" href="/tracing/base/math/range.html"> | 8 <link rel="import" href="/tracing/base/math/range.html"> |
9 <link rel="import" href="/tracing/base/multi_dimensional_view.html"> | 9 <link rel="import" href="/tracing/base/multi_dimensional_view.html"> |
10 <link rel="import" href="/tracing/base/unit.html"> | 10 <link rel="import" href="/tracing/base/unit.html"> |
11 <link rel="import" href="/tracing/base/utils.html"> | 11 <link rel="import" href="/tracing/base/utils.html"> |
12 <link rel="import" href="/tracing/extras/chrome/chrome_processes.html"> | 12 <link rel="import" href="/tracing/extras/chrome/chrome_processes.html"> |
13 <link rel="import" href="/tracing/metrics/metric_registry.html"> | 13 <link rel="import" href="/tracing/metrics/metric_registry.html"> |
| 14 <link rel="import" href="/tracing/metrics/system_health/utils.html"> |
14 <link rel="import" href="/tracing/model/container_memory_dump.html"> | 15 <link rel="import" href="/tracing/model/container_memory_dump.html"> |
15 <link rel="import" href="/tracing/model/helpers/chrome_model_helper.html"> | 16 <link rel="import" href="/tracing/model/helpers/chrome_model_helper.html"> |
16 <link rel="import" href="/tracing/model/memory_allocator_dump.html"> | 17 <link rel="import" href="/tracing/model/memory_allocator_dump.html"> |
17 <link rel="import" href="/tracing/value/diagnostics/breakdown.html"> | 18 <link rel="import" href="/tracing/value/diagnostics/breakdown.html"> |
18 <link rel="import" href="/tracing/value/histogram.html"> | 19 <link rel="import" href="/tracing/value/histogram.html"> |
19 | 20 |
20 <script> | 21 <script> |
21 'use strict'; | 22 'use strict'; |
22 | 23 |
23 tr.exportTo('tr.metrics.sh', function() { | 24 tr.exportTo('tr.metrics.sh', function() { |
(...skipping 26 matching lines...) Expand all Loading... |
50 .addBinBoundary(1024 /* 1 KiB */) | 51 .addBinBoundary(1024 /* 1 KiB */) |
51 .addExponentialBins(16 * 1024 * 1024 * 1024 /* 16 GiB */, 4 * 24)); | 52 .addExponentialBins(16 * 1024 * 1024 * 1024 /* 16 GiB */, 4 * 24)); |
52 | 53 |
53 const CHROME_PROCESS_NAMES = | 54 const CHROME_PROCESS_NAMES = |
54 tr.e.chrome.chrome_processes.CHROME_PROCESS_NAMES; | 55 tr.e.chrome.chrome_processes.CHROME_PROCESS_NAMES; |
55 | 56 |
56 function memoryMetric(values, model, opt_options) { | 57 function memoryMetric(values, model, opt_options) { |
57 const rangeOfInterest = | 58 const rangeOfInterest = |
58 opt_options ? opt_options.rangeOfInterest : undefined; | 59 opt_options ? opt_options.rangeOfInterest : undefined; |
59 const browserNameToGlobalDumps = | 60 const browserNameToGlobalDumps = |
60 splitGlobalDumpsByBrowserName(model, rangeOfInterest); | 61 tr.metrics.sh.splitGlobalDumpsByBrowserName(model, rangeOfInterest); |
61 addGeneralMemoryDumpValues(browserNameToGlobalDumps, values); | 62 addGeneralMemoryDumpValues(browserNameToGlobalDumps, values); |
62 addDetailedMemoryDumpValues(browserNameToGlobalDumps, values); | 63 addDetailedMemoryDumpValues(browserNameToGlobalDumps, values); |
63 addMemoryDumpCountValues(browserNameToGlobalDumps, values); | 64 addMemoryDumpCountValues(browserNameToGlobalDumps, values); |
64 } | 65 } |
65 | 66 |
66 /** | |
67 * Splits the global memory dumps in |model| by browser name. | |
68 * | |
69 * @param {!tr.Model} model The trace model from which the global dumps | |
70 * should be extracted. | |
71 * @param {!tr.b.math.Range=} opt_rangeOfInterest If provided, global memory | |
72 * dumps that do not inclusively intersect the range will be skipped. | |
73 * @return {!Map<string, !Array<!tr.model.GlobalMemoryDump>} A map from | |
74 * browser names to the associated global memory dumps. | |
75 */ | |
76 function splitGlobalDumpsByBrowserName(model, opt_rangeOfInterest) { | |
77 const chromeModelHelper = | |
78 model.getOrCreateHelper(tr.model.helpers.ChromeModelHelper); | |
79 const browserNameToGlobalDumps = new Map(); | |
80 const globalDumpToBrowserHelper = new WeakMap(); | |
81 | |
82 // 1. For each browser process in the model, add its global memory dumps to | |
83 // |browserNameToGlobalDumps|. |chromeModelHelper| can be undefined if | |
84 // it fails to find any browser, renderer or GPU process (see | |
85 // tr.model.helpers.ChromeModelHelper.supportsModel). | |
86 if (chromeModelHelper) { | |
87 chromeModelHelper.browserHelpers.forEach(function(helper) { | |
88 // Retrieve the associated global memory dumps and check that they | |
89 // haven't been classified as belonging to another browser process. | |
90 const globalDumps = skipDumpsThatDoNotIntersectRange( | |
91 helper.process.memoryDumps.map(d => d.globalMemoryDump), | |
92 opt_rangeOfInterest); | |
93 globalDumps.forEach(function(globalDump) { | |
94 const existingHelper = globalDumpToBrowserHelper.get(globalDump); | |
95 if (existingHelper !== undefined) { | |
96 throw new Error('Memory dump ID clash across multiple browsers ' + | |
97 'with PIDs: ' + existingHelper.pid + ' and ' + helper.pid); | |
98 } | |
99 globalDumpToBrowserHelper.set(globalDump, helper); | |
100 }); | |
101 | |
102 makeKeyUniqueAndSet(browserNameToGlobalDumps, | |
103 tr.e.chrome.chrome_processes.canonicalizeName(helper.browserName), | |
104 globalDumps); | |
105 }); | |
106 } | |
107 | |
108 // 2. If any global memory dump does not have any associated browser | |
109 // process for some reason, associate it with an 'unknown_browser' browser | |
110 // so that we don't lose the data. | |
111 const unclassifiedGlobalDumps = skipDumpsThatDoNotIntersectRange( | |
112 model.globalMemoryDumps.filter(g => !globalDumpToBrowserHelper.has(g)), | |
113 opt_rangeOfInterest); | |
114 if (unclassifiedGlobalDumps.length > 0) { | |
115 makeKeyUniqueAndSet( | |
116 browserNameToGlobalDumps, 'unknown_browser', unclassifiedGlobalDumps); | |
117 } | |
118 | |
119 return browserNameToGlobalDumps; | |
120 } | |
121 | |
122 function skipDumpsThatDoNotIntersectRange(dumps, opt_range) { | |
123 if (!opt_range) return dumps; | |
124 return dumps.filter(d => opt_range.intersectsExplicitRangeInclusive( | |
125 d.start, d.end)); | |
126 } | |
127 | |
128 | |
129 const USER_FRIENDLY_BROWSER_NAMES = { | 67 const USER_FRIENDLY_BROWSER_NAMES = { |
130 'chrome': 'Chrome', | 68 'chrome': 'Chrome', |
131 'webview': 'WebView', | 69 'webview': 'WebView', |
132 'unknown_browser': 'an unknown browser' | 70 'unknown_browser': 'an unknown browser' |
133 }; | 71 }; |
134 | 72 |
135 /** | 73 /** |
136 * Convert a canonical browser name used in value names to a user-friendly | 74 * Convert a canonical browser name used in value names to a user-friendly |
137 * name used in value descriptions. | 75 * name used in value descriptions. |
138 * | 76 * |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
178 case CHROME_PROCESS_NAMES.ALL: | 116 case CHROME_PROCESS_NAMES.ALL: |
179 return 'all processes'; | 117 return 'all processes'; |
180 case CHROME_PROCESS_NAMES.UNKNOWN: | 118 case CHROME_PROCESS_NAMES.UNKNOWN: |
181 return 'unknown processes'; | 119 return 'unknown processes'; |
182 default: | 120 default: |
183 return '\'' + processName + '\' processes'; | 121 return '\'' + processName + '\' processes'; |
184 } | 122 } |
185 } | 123 } |
186 | 124 |
187 /** | 125 /** |
188 * Function for adding entries with duplicate keys to a map without | |
189 * overriding existing entries. | |
190 * | |
191 * This is achieved by appending numeric indices (2, 3, 4, ...) to duplicate | |
192 * keys. Example: | |
193 * | |
194 * const map = new Map(); | |
195 * // map = Map {}. | |
196 * | |
197 * makeKeyUniqueAndSet(map, 'key', 'a'); | |
198 * // map = Map {"key" => "a"}. | |
199 * | |
200 * makeKeyUniqueAndSet(map, 'key', 'b'); | |
201 * // map = Map {"key" => "a", "key2" => "b"}. | |
202 * ^^^^ | |
203 * makeKeyUniqueAndSet(map, 'key', 'c'); | |
204 * // map = Map {"key" => "a", "key2" => "b", "key3" => "c"}. | |
205 * ^^^^ ^^^^ | |
206 */ | |
207 function makeKeyUniqueAndSet(map, key, value) { | |
208 let uniqueKey = key; | |
209 let nextIndex = 2; | |
210 while (map.has(uniqueKey)) { | |
211 uniqueKey = key + nextIndex; | |
212 nextIndex++; | |
213 } | |
214 map.set(uniqueKey, value); | |
215 } | |
216 | |
217 /** | |
218 * Add general memory dump values calculated from all global memory dumps to | 126 * Add general memory dump values calculated from all global memory dumps to |
219 * |values|. In particular, this function adds the following values: | 127 * |values|. In particular, this function adds the following values: |
220 * | 128 * |
221 * * PROCESS COUNTS | 129 * * PROCESS COUNTS |
222 * memory:{chrome, webview}: | 130 * memory:{chrome, webview}: |
223 * {browser_process, renderer_processes, ..., all_processes}: | 131 * {browser_process, renderer_processes, ..., all_processes}: |
224 * process_count | 132 * process_count |
225 * type: tr.v.Histogram (over all matching global memory dumps) | 133 * type: tr.v.Histogram (over all matching global memory dumps) |
226 * unit: count_smallerIsBetter | 134 * unit: count_smallerIsBetter |
227 * | 135 * |
(...skipping 998 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1226 | 1134 |
1227 tr.metrics.MetricRegistry.register(memoryMetric, { | 1135 tr.metrics.MetricRegistry.register(memoryMetric, { |
1228 supportsRangeOfInterest: true | 1136 supportsRangeOfInterest: true |
1229 }); | 1137 }); |
1230 | 1138 |
1231 return { | 1139 return { |
1232 memoryMetric, | 1140 memoryMetric, |
1233 }; | 1141 }; |
1234 }); | 1142 }); |
1235 </script> | 1143 </script> |
OLD | NEW |