Index: tracing/tracing/metrics/system_health/memory_metric.html |
diff --git a/tracing/tracing/metrics/system_health/memory_metric.html b/tracing/tracing/metrics/system_health/memory_metric.html |
index 1aa81e05b2b1a6e306adca5b6b0ce6d9d3029ecd..acccd77c6b37cc50f1abfaf9c04ecf8bf258752d 100644 |
--- a/tracing/tracing/metrics/system_health/memory_metric.html |
+++ b/tracing/tracing/metrics/system_health/memory_metric.html |
@@ -48,8 +48,10 @@ tr.exportTo('tr.metrics.sh', function() { |
.addBinBoundary(1024 /* 1 KiB */) |
.addExponentialBins(16 * 1024 * 1024 * 1024 /* 16 GiB */, 4 * 24)); |
- function memoryMetric(values, model) { |
- var browserNameToGlobalDumps = splitGlobalDumpsByBrowserName(model); |
+ function memoryMetric(values, model, opt_options) { |
+ var rangeOfInterest = opt_options ? opt_options.rangeOfInterest : undefined; |
+ var browserNameToGlobalDumps = |
+ splitGlobalDumpsByBrowserName(model, rangeOfInterest); |
addGeneralMemoryDumpValues(browserNameToGlobalDumps, values); |
addDetailedMemoryDumpValues(browserNameToGlobalDumps, values); |
addMemoryDumpCountValues(browserNameToGlobalDumps, values); |
@@ -60,10 +62,12 @@ tr.exportTo('tr.metrics.sh', function() { |
* |
* @param {!tr.Model} model The trace model from which the global dumps |
* should be extracted. |
+ * @param {!tr.b.Range=} opt_rangeOfInterest If proided, global memory dumps |
+ * that do not inclusively intersect the range will be skipped. |
* @return {!Map<string, !Array<!tr.model.GlobalMemoryDump>} A map from |
* browser names to the associated global memory dumps. |
*/ |
- function splitGlobalDumpsByBrowserName(model) { |
+ function splitGlobalDumpsByBrowserName(model, opt_rangeOfInterest) { |
var chromeModelHelper = |
model.getOrCreateHelper(tr.model.helpers.ChromeModelHelper); |
var browserNameToGlobalDumps = new Map(); |
@@ -77,8 +81,9 @@ tr.exportTo('tr.metrics.sh', function() { |
chromeModelHelper.browserHelpers.forEach(function(helper) { |
// Retrieve the associated global memory dumps and check that they |
// haven't been classified as belonging to another browser process. |
- var globalDumps = helper.process.memoryDumps.map( |
- d => d.globalMemoryDump); |
+ var globalDumps = skipDumpsThatDoNotIntersectRange( |
+ helper.process.memoryDumps.map(d => d.globalMemoryDump), |
+ opt_rangeOfInterest); |
globalDumps.forEach(function(globalDump) { |
var existingHelper = globalDumpToBrowserHelper.get(globalDump); |
if (existingHelper !== undefined) { |
@@ -96,8 +101,9 @@ tr.exportTo('tr.metrics.sh', function() { |
// 2. If any global memory dump does not have any associated browser |
// process for some reason, associate it with an 'unknown_browser' browser |
// so that we don't lose the data. |
- var unclassifiedGlobalDumps = |
- model.globalMemoryDumps.filter(g => !globalDumpToBrowserHelper.has(g)); |
+ var unclassifiedGlobalDumps = skipDumpsThatDoNotIntersectRange( |
+ model.globalMemoryDumps.filter(g => !globalDumpToBrowserHelper.has(g)), |
+ opt_rangeOfInterest); |
if (unclassifiedGlobalDumps.length > 0) { |
makeKeyUniqueAndSet( |
browserNameToGlobalDumps, 'unknown_browser', unclassifiedGlobalDumps); |
@@ -106,6 +112,13 @@ tr.exportTo('tr.metrics.sh', function() { |
return browserNameToGlobalDumps; |
} |
+ function skipDumpsThatDoNotIntersectRange(dumps, opt_range) { |
+ if (!opt_range) |
+ return dumps; |
+ return dumps.filter(d => opt_range.intersectsExplicitRangeInclusive( |
+ d.start, d.end)); |
+ } |
+ |
function canonicalizeName(name) { |
return name.toLowerCase().replace(' ', '_'); |
}; |
@@ -246,16 +259,45 @@ tr.exportTo('tr.metrics.sh', function() { |
if (processDump.memoryAllocatorDumps === undefined) |
return; |
processDump.memoryAllocatorDumps.forEach(function(rootAllocatorDump) { |
- CHROME_VALUE_PROPERTIES.forEach(function(spec) { |
+ tr.b.iterItems(CHROME_VALUE_PROPERTIES, |
+ function(propertyName, descriptionPrefixBuilder) { |
+ addProcessScalar({ |
+ source: 'reported_by_chrome', |
+ component: [rootAllocatorDump.name], |
+ property: propertyName, |
+ value: rootAllocatorDump.numerics[propertyName], |
+ descriptionPrefixBuilder: descriptionPrefixBuilder |
+ }); |
+ }); |
+ }); |
+ // Add memory:<browser-name>:<process-name>:reported_by_chrome:v8: |
+ // allocated_by_malloc:effective_size when available. |
+ var v8Dump = processDump.getMemoryAllocatorDumpByFullName('v8'); |
+ if (v8Dump !== undefined) { |
+ var allocatedByMalloc = 0; |
+ var hasMallocDump = false; |
+ v8Dump.children.forEach(function(isolateDump) { |
+ var mallocDump = |
+ isolateDump.getDescendantDumpByFullName('malloc'); |
+ if (mallocDump === undefined || |
+ mallocDump.numerics['effective_size'] === undefined) { |
+ return; |
+ } |
+ allocatedByMalloc += mallocDump.numerics['effective_size'].value; |
+ hasMallocDump = true; |
+ }); |
+ if (hasMallocDump) { |
addProcessScalar({ |
source: 'reported_by_chrome', |
- component: [rootAllocatorDump.name], |
- property: spec.propertyName, |
- value: rootAllocatorDump.numerics[spec.propertyName], |
- descriptionPrefixBuilder: spec.descriptionPrefixBuilder |
+ component: ['v8', 'allocated_by_malloc'], |
+ property: 'effective_size', |
+ value: allocatedByMalloc, |
+ unit: sizeInBytes_smallerIsBetter, |
+ descriptionPrefixBuilder: |
+ CHROME_VALUE_PROPERTIES['effective_size'] |
}); |
- }); |
- }); |
+ } |
+ } |
}, |
function(componentTree) { |
// Subtract memory:<browser-name>:<process-name>:reported_by_chrome: |
@@ -332,7 +374,13 @@ tr.exportTo('tr.metrics.sh', function() { |
nameParts.push(formatSpec.userFriendlyPropertyNamePrefix); |
nameParts.push(formatSpec.userFriendlyPropertyName); |
nameParts.push(formatSpec.componentPreposition); |
- nameParts.push(componentPath.join(':')); |
+ if (componentPath[componentPath.length - 1] === 'allocated_by_malloc') { |
+ nameParts.push('objects allocated by malloc for'); |
+ nameParts.push( |
+ componentPath.slice(0, componentPath.length - 1).join(':')); |
+ } else { |
+ nameParts.push(componentPath.join(':')); |
+ } |
} |
nameParts.push('in'); |
} |
@@ -341,33 +389,22 @@ tr.exportTo('tr.metrics.sh', function() { |
} |
// Specifications of properties reported by Chrome. |
- var CHROME_VALUE_PROPERTIES = [ |
- { |
- propertyName: 'effective_size', |
- descriptionPrefixBuilder: buildChromeValueDescriptionPrefix.bind( |
- undefined, { |
- userFriendlyPropertyName: 'effective size', |
- componentPreposition: 'of' |
- }) |
- }, |
- { |
- propertyName: 'allocated_objects_size', |
- descriptionPrefixBuilder: buildChromeValueDescriptionPrefix.bind( |
- undefined, { |
- userFriendlyPropertyName: 'size of all objects allocated', |
- totalUserFriendlyPropertyName: 'size of all allocated objects', |
- componentPreposition: 'by' |
- }) |
- }, |
- { |
- propertyName: 'locked_size', |
- descriptionPrefixBuilder: buildChromeValueDescriptionPrefix.bind( |
- undefined, { |
- userFriendlyPropertyName: 'locked (pinned) size', |
- componentPreposition: 'of' |
- }) |
- } |
- ]; |
+ var CHROME_VALUE_PROPERTIES = { |
+ 'effective_size': buildChromeValueDescriptionPrefix.bind(undefined, { |
+ userFriendlyPropertyName: 'effective size', |
+ componentPreposition: 'of' |
+ }), |
+ 'allocated_objects_size': buildChromeValueDescriptionPrefix.bind( |
+ undefined, { |
+ userFriendlyPropertyName: 'size of all objects allocated', |
+ totalUserFriendlyPropertyName: 'size of all allocated objects', |
+ componentPreposition: 'by' |
+ }), |
+ 'locked_size': buildChromeValueDescriptionPrefix.bind(undefined, { |
+ userFriendlyPropertyName: 'locked (pinned) size', |
+ componentPreposition: 'of' |
+ }) |
+ }; |
/** |
* Add heavy memory dump values calculated from heavy global memory dumps to |
@@ -1014,7 +1051,9 @@ tr.exportTo('tr.metrics.sh', function() { |
return numeric; |
} |
- tr.metrics.MetricRegistry.register(memoryMetric); |
+ tr.metrics.MetricRegistry.register(memoryMetric, { |
+ supportsRangeOfInterest: true |
+ }); |
return { |
memoryMetric: memoryMetric |