Skip to content

Commit

Permalink
Order the retainers by their distance to root.
Browse files Browse the repository at this point in the history
  • Loading branch information
filipnavara committed Aug 10, 2023
1 parent 83a0d15 commit 8637b12
Show file tree
Hide file tree
Showing 2 changed files with 48 additions and 3 deletions.
38 changes: 38 additions & 0 deletions src/OneHub.Diagnostics.HeapView/HeapSnapshot.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,19 +12,22 @@ public class HeapSnapshot
private RefGraph refGraph;

private int[] postOrderIndex2NodeIndex;
private int[] nodeIndex2Depth;
//private int[]? nodeIndex2PostOrderIndex;
//private int[] dominatorsTree;
private ulong[] retainedSizes;

public MemoryGraph MemoryGraph => heapDump.MemoryGraph;
public RefGraph RefGraph => refGraph;
public ulong GetRetainedSize(NodeIndex nodeIndex) => retainedSizes[(int)nodeIndex];
public int GetDepth(NodeIndex nodeIndex) => nodeIndex2Depth[(int)nodeIndex];

public HeapSnapshot(GCHeapDump heapDump)

Check warning on line 25 in src/OneHub.Diagnostics.HeapView/HeapSnapshot.cs

View workflow job for this annotation

GitHub Actions / build

Non-nullable field 'nodeIndex2Depth' must contain a non-null value when exiting constructor. Consider declaring the field as nullable.

Check warning on line 25 in src/OneHub.Diagnostics.HeapView/HeapSnapshot.cs

View workflow job for this annotation

GitHub Actions / build

Non-nullable field 'nodeIndex2Depth' must contain a non-null value when exiting constructor. Consider declaring the field as nullable.
{
this.heapDump = heapDump;
this.refGraph = new RefGraph(heapDump.MemoryGraph);
BuildPostOrderIndex();
BuildDepthIndex();
CalculateRetainedSizes();
Debug.Assert(postOrderIndex2NodeIndex != null);
Debug.Assert(retainedSizes != null);
Expand Down Expand Up @@ -67,6 +70,41 @@ private void BuildPostOrderIndex()
}
}

private void BuildDepthIndex()
{
var graph = this.heapDump.MemoryGraph;
nodeIndex2Depth = new int[(int)graph.NodeIndexLimit];
var visited = new BitArray((int)graph.NodeIndexLimit);
var nodeStack = new Stack<NodeIndex>();
var nodeStack2 = new Stack<NodeIndex>();
var nodeStorage = graph.AllocNodeStorage();
int depth = 0;

nodeStack.Push(graph.RootIndex);
visited.Set((int)graph.RootIndex, true);
while (nodeStack.Count > 0)
{
while (nodeStack.Count > 0)
{
var currentNode = graph.GetNode(nodeStack.Pop(), nodeStorage);
nodeIndex2Depth[(int)currentNode.Index] = depth;
for (NodeIndex childIndex = currentNode.GetFirstChildIndex();
childIndex != NodeIndex.Invalid;
childIndex = currentNode.GetNextChildIndex())
{
if (!visited.Get((int)childIndex))
{
nodeStack2.Push(childIndex);
visited.Set((int)childIndex, true);
}
}
}

(nodeStack2, nodeStack) = (nodeStack, nodeStack2);
depth++;
}
}

private void CalculateRetainedSizes()
{
retainedSizes = new ulong[(int)heapDump.MemoryGraph.NodeIndexLimit];
Expand Down
13 changes: 10 additions & 3 deletions src/OneHub.Diagnostics.HeapView/HeapView.axaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -40,16 +40,21 @@ public HeapView()

heapSource.SortBy(retainedSizeColumn, System.ComponentModel.ListSortDirection.Descending);

TextColumn<IMemoryNode, int> distanceToRootColumn;

retainersSource = new HierarchicalTreeDataGridSource<IMemoryNode>(retainersNodes)
{
Columns =
{
new HierarchicalExpanderColumn<IMemoryNode>(
new TextColumn<IMemoryNode, string>("Name", x => x.Name, GridLength.Star),
x => x.Children),
(distanceToRootColumn = new TextColumn<IMemoryNode, int>("Distance to root", x => x.Depth)),
},
};

retainersSource.SortBy(distanceToRootColumn, System.ComponentModel.ListSortDirection.Ascending);

heapSource.RowSelection!.SelectionChanged += RowSelection_SelectionChanged;

heapTree.Source = heapSource;
Expand Down Expand Up @@ -110,7 +115,8 @@ public interface IMemoryNode
string Name { get; }
ulong Size { get; }
ulong RetainedSize { get; }
IReadOnlyList<IMemoryNode> Children { get; }
int Depth { get; }
IReadOnlyList <IMemoryNode> Children { get; }
}

class MemoryNode : IMemoryNode
Expand All @@ -124,7 +130,6 @@ public MemoryNode(HeapSnapshot heapSnapshot, Node node, string? name = null, boo
var address = heapSnapshot.MemoryGraph.GetAddress(node.Index);
Name = address > 0 ? $"{name} @ {address:x}" : name;
Size = (ulong)node.Size;
RetainedSize = heapSnapshot.GetRetainedSize(node.Index);
HeapSnapshot = heapSnapshot;
NodeIndex = node.Index;
ChildrenAreRetainers = childrenAreRetainers;
Expand All @@ -135,7 +140,8 @@ public MemoryNode(HeapSnapshot heapSnapshot, Node node, string? name = null, boo

public string Name { get; init; }
public ulong Size { get; init; }
public ulong RetainedSize { get; init; }
public ulong RetainedSize => HeapSnapshot.GetRetainedSize(NodeIndex);
public int Depth => HeapSnapshot.GetDepth(NodeIndex);
public bool ChildrenAreRetainers { get; init; }

public IReadOnlyList<IMemoryNode> Children
Expand Down Expand Up @@ -184,6 +190,7 @@ class GroupedTypeMemoryNode : IMemoryNode
public required string Name { get; init; }
public ulong Size { get; set; } = 0;
public ulong RetainedSize { get; set; } = 0;
public int Depth => 0;
public IReadOnlyList<IMemoryNode> Children => MutableChildren;
public List<IMemoryNode> MutableChildren { get; } = new List<IMemoryNode>();
}
Expand Down

0 comments on commit 8637b12

Please sign in to comment.