Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(623)

Unified Diff: runtime/observatory/lib/src/elements/heap_snapshot.dart

Issue 2480293003: Observatory: Add view of dominator tree with siblings merged by class. (Closed)
Patch Set: . Created 4 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: runtime/observatory/lib/src/elements/heap_snapshot.dart
diff --git a/runtime/observatory/lib/src/elements/heap_snapshot.dart b/runtime/observatory/lib/src/elements/heap_snapshot.dart
index 2fd6e7882247f5d014aa80cb3cb8b53602f3f691..03e981ce09dbdc1c12d33b1efb9732e0df5787c7 100644
--- a/runtime/observatory/lib/src/elements/heap_snapshot.dart
+++ b/runtime/observatory/lib/src/elements/heap_snapshot.dart
@@ -24,7 +24,7 @@ import 'package:observatory/src/elements/nav/top_menu.dart';
import 'package:observatory/src/elements/nav/vm_menu.dart';
import 'package:observatory/utils.dart';
-enum HeapSnapshotTreeMode { dominatorTree, groupByClass }
+enum HeapSnapshotTreeMode { dominatorTree, mergedDominatorTree, groupByClass }
class HeapSnapshotElement extends HtmlElement implements Renderable {
static const tag =
@@ -266,6 +266,31 @@ class HeapSnapshotElement extends HtmlElement implements Renderable {
_tree
]);
break;
+ case HeapSnapshotTreeMode.mergedDominatorTree:
+ _tree = new VirtualTreeElement(
+ _createMergedDominator, _updateMergedDominator,
+ _getChildrenMergedDominator,
+ items: _getChildrenMergedDominator(_snapshot.mergedDominatorTree),
+ queue: _r.queue);
+ _tree.expand(_snapshot.mergedDominatorTree);
+ final text = 'In a heap dominator tree, an object X is a parent of '
+ 'object Y if every path from the root to Y goes through '
+ 'X. This allows you to find "choke points" that are '
+ 'holding onto a lot of memory. If an object becomes '
+ 'garbage, all its children in the dominator tree become '
+ 'garbage as well. '
+ 'The retained size of an object is the sum of the '
+ 'retained sizes of its children in the dominator tree '
Cutch 2016/11/14 17:24:13 This text should explain what "merge" means in mor
rmacnak 2016/11/15 00:44:15 Done.
+ 'plus its own shallow size, and is the amount of memory '
+ 'that would be freed if the object became garbage.';
+ report.addAll([
+ new DivElement()
+ ..classes = ['content-centered-big', 'explanation']
+ ..text = text
+ ..title = text,
+ _tree
+ ]);
+ break;
case HeapSnapshotTreeMode.groupByClass:
final items = _snapshot.classReferences.toList();
items.sort((a, b) => b.shallowSize - a.shallowSize);
@@ -299,6 +324,24 @@ class HeapSnapshotElement extends HtmlElement implements Renderable {
];
}
+ static Element _createMergedDominator(toggle) {
+ return new DivElement()
+ ..classes = ['tree-item']
+ ..children = [
+ new SpanElement()
+ ..classes = ['size']
+ ..title = 'retained size',
+ new SpanElement()..classes = ['lines'],
+ new ButtonElement()
+ ..classes = ['expander']
+ ..onClick.listen((_) => toggle(autoToggleSingleChildNodes: true)),
+ new SpanElement()
+ ..classes = ['percentage']
+ ..title = 'percentage of heap being retained',
+ new SpanElement()..classes = ['name']
+ ];
+ }
+
static Element _createGroup(toggle) {
return new DivElement()
..classes = ['tree-item']
@@ -327,6 +370,13 @@ class HeapSnapshotElement extends HtmlElement implements Renderable {
.where((child) => child.retainedSize >= kMinRetainedSize)
.take(kMaxChildren);
}
+ static _getChildrenMergedDominator(M.HeapSnapshotMergedDominatorNode node) {
+ final list = node.children.toList();
+ list.sort((a, b) => b.retainedSize - a.retainedSize);
+ return list
+ .where((child) => child.retainedSize >= kMinRetainedSize)
+ .take(kMaxChildren);
+ }
static _getChildrenGroup(item) {
if (item is M.HeapSnapshotClassReferences) {
@@ -361,6 +411,31 @@ class HeapSnapshotElement extends HtmlElement implements Renderable {
});
}
+ void _updateMergedDominator(
+ HtmlElement element, M.HeapSnapshotMergedDominatorNode node, int depth) {
+ element.children[0].text = Utils.formatSize(node.retainedSize);
+ _updateLines(element.children[1].children, depth);
+ if (_getChildrenMergedDominator(node).isNotEmpty) {
+ element.children[2].text = _tree.isExpanded(node) ? '▼' : '►';
+ } else {
+ element.children[2].text = '';
+ }
+ element.children[3].text =
+ Utils.formatPercentNormalized(node.retainedSize * 1.0 / _snapshot.size);
+ final wrapper = new SpanElement()
+ ..classes = ['name']
+ ..text = 'Loading...';
+ element.children[4] = wrapper;
+ node.klass.then((klass) {
+ wrapper
+ ..text = ''
+ ..children = [
+ new SpanElement()..text = '${node.instanceCount} instances of ',
+ anyRef(_isolate, klass, _instances, queue: _r.queue)
+ ];
+ });
+ }
+
void _updateGroup(HtmlElement element, item, int depth) {
_updateLines(element.children[1].children, depth);
if (item is M.HeapSnapshotClassReferences) {
@@ -424,6 +499,8 @@ class HeapSnapshotElement extends HtmlElement implements Renderable {
switch (mode) {
case HeapSnapshotTreeMode.dominatorTree:
return 'Dominator tree';
+ case HeapSnapshotTreeMode.mergedDominatorTree:
+ return 'Dominator tree (merged siblings by class)';
case HeapSnapshotTreeMode.groupByClass:
return 'Group by class';
}

Powered by Google App Engine
This is Rietveld 408576698