| 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/iteration_helpers.html"> | 8 <link rel="import" href="/tracing/base/iteration_helpers.html"> |
| 9 <link rel="import" href="/tracing/base/range.html"> | 9 <link rel="import" href="/tracing/base/range.html"> |
| 10 <link rel="import" href="/tracing/metrics/metric_registry.html"> | 10 <link rel="import" href="/tracing/metrics/metric_registry.html"> |
| 11 <link rel="import" href="/tracing/model/container_memory_dump.html"> | 11 <link rel="import" href="/tracing/model/container_memory_dump.html"> |
| 12 <link rel="import" href="/tracing/model/helpers/chrome_model_helper.html"> | 12 <link rel="import" href="/tracing/model/helpers/chrome_model_helper.html"> |
| 13 <link rel="import" href="/tracing/model/memory_allocator_dump.html"> | 13 <link rel="import" href="/tracing/model/memory_allocator_dump.html"> |
| 14 <link rel="import" href="/tracing/value/numeric.html"> | 14 <link rel="import" href="/tracing/value/numeric.html"> |
| 15 <link rel="import" href="/tracing/value/unit.html"> | 15 <link rel="import" href="/tracing/value/unit.html"> |
| 16 <link rel="import" href="/tracing/value/value.html"> | 16 <link rel="import" href="/tracing/value/value.html"> |
| 17 | 17 |
| 18 <script> | 18 <script> |
| 19 'use strict'; | 19 'use strict'; |
| 20 | 20 |
| 21 tr.exportTo('tr.metrics.sh', function() { | 21 tr.exportTo('tr.metrics.sh', function() { |
| 22 | 22 |
| 23 var DISPLAYED_SIZE_NUMERIC_NAME = | |
| 24 tr.model.MemoryAllocatorDump.DISPLAYED_SIZE_NUMERIC_NAME; | |
| 25 var LIGHT = tr.model.ContainerMemoryDump.LevelOfDetail.LIGHT; | 23 var LIGHT = tr.model.ContainerMemoryDump.LevelOfDetail.LIGHT; |
| 26 var DETAILED = tr.model.ContainerMemoryDump.LevelOfDetail.DETAILED; | 24 var DETAILED = tr.model.ContainerMemoryDump.LevelOfDetail.DETAILED; |
| 27 var ScalarNumeric = tr.v.ScalarNumeric; | 25 var ScalarNumeric = tr.v.ScalarNumeric; |
| 28 var sizeInBytes_smallerIsBetter = | 26 var sizeInBytes_smallerIsBetter = |
| 29 tr.v.Unit.byName.sizeInBytes_smallerIsBetter; | 27 tr.v.Unit.byName.sizeInBytes_smallerIsBetter; |
| 30 var unitlessNumber_smallerIsBetter = | 28 var unitlessNumber_smallerIsBetter = |
| 31 tr.v.Unit.byName.unitlessNumber_smallerIsBetter; | 29 tr.v.Unit.byName.unitlessNumber_smallerIsBetter; |
| 32 | 30 |
| 33 var MMAPS_METRICS = { | 31 var MMAPS_VALUES = { |
| 34 'overall:pss': { | 32 'overall:pss': { |
| 35 path: [], | 33 path: [], |
| 36 byteStat: 'proportionalResident' | 34 byteStat: 'proportionalResident' |
| 37 }, | 35 }, |
| 38 'overall:private_dirty': { | 36 'overall:private_dirty': { |
| 39 path: [], | 37 path: [], |
| 40 byteStat: 'privateDirtyResident' | 38 byteStat: 'privateDirtyResident' |
| 41 }, | 39 }, |
| 42 'java_heap:private_dirty': { | 40 'java_heap:private_dirty': { |
| 43 path: ['Android', 'Java runtime', 'Spaces'], | 41 path: ['Android', 'Java runtime', 'Spaces'], |
| 44 byteStat: 'privateDirtyResident' | 42 byteStat: 'privateDirtyResident' |
| 45 }, | 43 }, |
| 46 'ashmem:pss': { | 44 'ashmem:pss': { |
| 47 path: ['Android', 'Ashmem'], | 45 path: ['Android', 'Ashmem'], |
| 48 byteStat: 'proportionalResident' | 46 byteStat: 'proportionalResident' |
| 49 }, | 47 }, |
| 50 'native_heap:pss': { | 48 'native_heap:pss': { |
| 51 path: ['Native heap'], | 49 path: ['Native heap'], |
| 52 byteStat: 'proportionalResident' | 50 byteStat: 'proportionalResident' |
| 53 } | 51 } |
| 54 }; | 52 }; |
| 55 | 53 |
| 54 var SUBSYSTEM_VALUES = [ |
| 55 tr.model.MemoryAllocatorDump.DISPLAYED_SIZE_NUMERIC_NAME, |
| 56 'allocated_objects_size' |
| 57 ]; |
| 58 |
| 56 var ALL_PROCESS_NAMES = 'all'; | 59 var ALL_PROCESS_NAMES = 'all'; |
| 57 | 60 |
| 58 var LEVEL_OF_DETAIL_NAMES = new Map(); | 61 var LEVEL_OF_DETAIL_NAMES = new Map(); |
| 59 LEVEL_OF_DETAIL_NAMES.set(LIGHT, 'light'); | 62 LEVEL_OF_DETAIL_NAMES.set(LIGHT, 'light'); |
| 60 LEVEL_OF_DETAIL_NAMES.set(DETAILED, 'detailed'); | 63 LEVEL_OF_DETAIL_NAMES.set(DETAILED, 'detailed'); |
| 61 | 64 |
| 62 var MEMORY_NUMERIC_BUILDER_MAP = new WeakMap(); | 65 var MEMORY_NUMERIC_BUILDER_MAP = new WeakMap(); |
| 63 // For unitless numerics (process counts), we use 20 linearly scaled bins | 66 // For unitless numerics (process counts), we use 20 linearly scaled bins |
| 64 // from 0 to 20. | 67 // from 0 to 20. |
| 65 MEMORY_NUMERIC_BUILDER_MAP.set(unitlessNumber_smallerIsBetter, | 68 MEMORY_NUMERIC_BUILDER_MAP.set(unitlessNumber_smallerIsBetter, |
| (...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 170 * |model| to |valueList|. In particular, this function adds the following | 173 * |model| to |valueList|. In particular, this function adds the following |
| 171 * values: | 174 * values: |
| 172 * | 175 * |
| 173 * * PROCESS COUNTS | 176 * * PROCESS COUNTS |
| 174 * memory:{chrome, webview}:{browser, renderer, ..., all}:process_count | 177 * memory:{chrome, webview}:{browser, renderer, ..., all}:process_count |
| 175 * type: tr.v.Numeric (histogram over all matching global memory dumps) | 178 * type: tr.v.Numeric (histogram over all matching global memory dumps) |
| 176 * unit: unitlessNumber_smallerIsBetter | 179 * unit: unitlessNumber_smallerIsBetter |
| 177 * | 180 * |
| 178 * * ALLOCATOR STATISTICS | 181 * * ALLOCATOR STATISTICS |
| 179 * memory:{chrome, webview}:{browser, renderer, ..., all}:subsystem: | 182 * memory:{chrome, webview}:{browser, renderer, ..., all}:subsystem: |
| 180 * {v8, malloc, ...} | 183 * {v8, malloc, ...}:{effective_size, allocated_objects_size} |
| 181 * memory:{chrome, webview}:{browser, renderer, ..., all}:subsystem: | 184 * memory:{chrome, webview}:{browser, renderer, ..., all}:subsystem: |
| 182 * {v8, malloc, ...}:allocated_objects | 185 * gpu:android_memtrack:{gl, ...}:memtrack_pss |
| 183 * memory:{chrome, webview}:{browser, renderer, ..., all}: | 186 * memory:{chrome, webview}:{browser, renderer, ..., all}:subsystem: |
| 184 * android_memtrack:{gl, ...} | 187 * discardable:locked_size |
| 185 * type: tr.v.Numeric (histogram over all matching global memory dumps) | 188 * type: tr.v.Numeric (histogram over all matching global memory dumps) |
| 186 * unit: sizeInBytes_smallerIsBetter | 189 * unit: sizeInBytes_smallerIsBetter |
| 187 */ | 190 */ |
| 188 function addGeneralMemoryDumpValues( | 191 function addGeneralMemoryDumpValues( |
| 189 browserNameToGlobalDumps, valueList, model) { | 192 browserNameToGlobalDumps, valueList, model) { |
| 190 addPerProcessNameMemoryDumpValues(browserNameToGlobalDumps, | 193 addPerProcessNameMemoryDumpValues(browserNameToGlobalDumps, |
| 191 gmd => true /* process all global memory dumps */, | 194 gmd => true /* process all global memory dumps */, |
| 192 function(processDump, addProcessScalar) { | 195 function(processDump, addProcessScalar) { |
| 193 // Increment process_count value. | 196 // Increment process_count value. |
| 194 addProcessScalar( | 197 addProcessScalar( |
| 195 'process_count', | 198 'process_count', |
| 196 new ScalarNumeric(unitlessNumber_smallerIsBetter, 1)); | 199 new ScalarNumeric(unitlessNumber_smallerIsBetter, 1)); |
| 197 | 200 |
| 198 if (processDump.memoryAllocatorDumps === undefined) | 201 if (processDump.memoryAllocatorDumps === undefined) |
| 199 return; | 202 return; |
| 200 | 203 |
| 201 // Add memory:<browser-name>:<process-name>:subsystem:<name> and | |
| 202 // memory:<browser-name>:<process-name>:subsystem:<name>: | |
| 203 // allocated_objects values for each root memory allocator dump. | |
| 204 processDump.memoryAllocatorDumps.forEach(function(rootAllocatorDump) { | 204 processDump.memoryAllocatorDumps.forEach(function(rootAllocatorDump) { |
| 205 addProcessScalar( | 205 var subsystemPrefix = 'subsystem:' + rootAllocatorDump.name; |
| 206 'subsystem:' + rootAllocatorDump.name, | 206 |
| 207 rootAllocatorDump.numerics[DISPLAYED_SIZE_NUMERIC_NAME]); | 207 // Add generic values for each root memory allocator dump |
| 208 addProcessScalar( | 208 // (memory:<browser-name>:<process-name>:subsystem:<name>: |
| 209 'subsystem:' + rootAllocatorDump.name + ':allocated_objects', | 209 // {effective_size, allocated_objects_size}). |
| 210 rootAllocatorDump.numerics['allocated_objects_size']); | 210 SUBSYSTEM_VALUES.forEach(function(valueName) { |
| 211 addProcessScalar( |
| 212 subsystemPrefix + ':' + valueName, |
| 213 rootAllocatorDump.numerics[valueName]); |
| 214 }); |
| 215 |
| 216 // Add subsystem-specific values. |
| 217 switch (rootAllocatorDump.name) { |
| 218 // memory:<browser-name>:<process-name>:subsystem:gpu: |
| 219 // android_memtrack:<component-name>:memtrack_pss. |
| 220 case 'gpu': |
| 221 var memtrackDump = |
| 222 rootAllocatorDump.getDescendantDumpByFullName( |
| 223 'android_memtrack'); |
| 224 if (memtrackDump !== undefined) { |
| 225 memtrackDump.children.forEach(function(memtrackChildDump) { |
| 226 addProcessScalar( |
| 227 subsystemPrefix + ':android_memtrack:' + |
| 228 memtrackChildDump.name + ':memtrack_pss', |
| 229 memtrackChildDump.numerics['memtrack_pss']); |
| 230 }); |
| 231 } |
| 232 break; |
| 233 // memory:<browser-name>:<process-name>:subsystem:discardable: |
| 234 // locked_size. |
| 235 case 'discardable': |
| 236 addProcessScalar( |
| 237 subsystemPrefix + ':locked_size', |
| 238 rootAllocatorDump.numerics['locked_size']); |
| 239 break; |
| 240 } |
| 211 }); | 241 }); |
| 212 | |
| 213 // Add memory:<browser-name>:<process-name>:android_memtrack:<name> | |
| 214 // value for each child of the gpu/android_memtrack memory allocator | |
| 215 // dump. | |
| 216 var memtrackDump = processDump.getMemoryAllocatorDumpByFullName( | |
| 217 'gpu/android_memtrack'); | |
| 218 if (memtrackDump !== undefined) { | |
| 219 memtrackDump.children.forEach(function(memtrackChildDump) { | |
| 220 addProcessScalar( | |
| 221 'android_memtrack:' + memtrackChildDump.name, | |
| 222 memtrackChildDump.numerics['memtrack_pss']); | |
| 223 }); | |
| 224 } | |
| 225 }, valueList, model); | 242 }, valueList, model); |
| 226 } | 243 } |
| 227 | 244 |
| 228 /** | 245 /** |
| 229 * Add heavy memory dump values calculated from heavy global memory dumps in | 246 * Add heavy memory dump values calculated from heavy global memory dumps in |
| 230 * |model| to |valueList|. In particular, this function adds the following | 247 * |model| to |valueList|. In particular, this function adds the following |
| 231 * values: | 248 * values: |
| 232 * | 249 * |
| 233 * * VIRTUAL MEMORY STATISTICS | 250 * * VIRTUAL MEMORY STATISTICS |
| 234 * memory:{chrome, webview}:{browser, renderer, ..., all}:vmstats: | 251 * memory:{chrome, webview}:{browser, renderer, ..., all}:vmstats: |
| 235 * {overall, ashmem, native_heap}:pss | 252 * {overall, ashmem, native_heap}:pss |
| 236 * memory:{chrome, webview}:{browser, renderer, ..., all}:vmstats: | 253 * memory:{chrome, webview}:{browser, renderer, ..., all}:vmstats: |
| 237 * {overall, java_heap}:private_dirty | 254 * {overall, java_heap}:private_dirty |
| 238 * type: tr.v.Numeric (histogram over matching heavy global memory dumps) | 255 * type: tr.v.Numeric (histogram over matching heavy global memory dumps) |
| 239 * unit: sizeInBytes_smallerIsBetter | 256 * unit: sizeInBytes_smallerIsBetter |
| 240 */ | 257 */ |
| 241 function addDetailedMemoryDumpValues( | 258 function addDetailedMemoryDumpValues( |
| 242 browserNameToGlobalDumps, valueList, model) { | 259 browserNameToGlobalDumps, valueList, model) { |
| 243 addPerProcessNameMemoryDumpValues(browserNameToGlobalDumps, | 260 addPerProcessNameMemoryDumpValues(browserNameToGlobalDumps, |
| 244 g => g.levelOfDetail === DETAILED, | 261 g => g.levelOfDetail === DETAILED, |
| 245 function(processDump, addProcessScalar) { | 262 function(processDump, addProcessScalar) { |
| 246 // Add memory:<browser-name>:<process-name>:vmstats:<name> value for | 263 // Add memory:<browser-name>:<process-name>:vmstats:<name> value for |
| 247 // each mmap metric. | 264 // each mmap metric. |
| 248 tr.b.iterItems(MMAPS_METRICS, function(metricName, metricSpec) { | 265 tr.b.iterItems(MMAPS_VALUES, function(valueName, valueSpec) { |
| 249 var node = getDescendantVmRegionClassificationNode( | 266 var node = getDescendantVmRegionClassificationNode( |
| 250 processDump.vmRegions, metricSpec.path); | 267 processDump.vmRegions, valueSpec.path); |
| 251 var value = node ? (node.byteStats[metricSpec.byteStat] || 0) : 0; | 268 var value = node ? (node.byteStats[valueSpec.byteStat] || 0) : 0; |
| 252 addProcessScalar( | 269 addProcessScalar( |
| 253 'vmstats:' + metricName, | 270 'vmstats:' + valueName, |
| 254 new ScalarNumeric(sizeInBytes_smallerIsBetter, value)); | 271 new ScalarNumeric(sizeInBytes_smallerIsBetter, value)); |
| 255 }); | 272 }); |
| 256 }, valueList, model); | 273 }, valueList, model); |
| 257 } | 274 } |
| 258 | 275 |
| 259 /** | 276 /** |
| 260 * Get the descendant of a VM region classification |node| specified by the | 277 * Get the descendant of a VM region classification |node| specified by the |
| 261 * given |path| of child node titles. If |node| is undefined or such a | 278 * given |path| of child node titles. If |node| is undefined or such a |
| 262 * descendant does not exist, this function returns undefined. | 279 * descendant does not exist, this function returns undefined. |
| 263 */ | 280 */ |
| (...skipping 262 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 526 return numeric; | 543 return numeric; |
| 527 } | 544 } |
| 528 | 545 |
| 529 tr.metrics.MetricRegistry.register(memoryMetric); | 546 tr.metrics.MetricRegistry.register(memoryMetric); |
| 530 | 547 |
| 531 return { | 548 return { |
| 532 memoryMetric: memoryMetric | 549 memoryMetric: memoryMetric |
| 533 }; | 550 }; |
| 534 }); | 551 }); |
| 535 </script> | 552 </script> |
| OLD | NEW |