| 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
|
|
|