Refactor ahat's perflib api.
This change substantially refactors how ahat accesses heap dump data.
Rather than use the perflib API directly with some additional
information accessed on the side via AhatSnapshot, we introduce an
entirely new API for accessing all the information we need from a heap
dump. Perflib is used when processing the heap dump to populate the
information initially, but afterwards all views and handlers go
through the new com.android.ahat.heapdump API.
The primary motivation for this change is to facilitate adding support
for diffing two heap dumps to ahat. The new API provides flexibility
that will make it easier to form links between objects in different
snapshots and introduce place holder objects to show when there is an
object in another snapshot that has no corresponding object in this
snapshot.
A large number of test cases were added to cover missing cases
discovered in the process of refactoring ahat's perflib API.
The external user-facing UI may have minor cosmetic changes, but
otherwise is unchanged.
Test: m ahat-test, with many new tests added.
Bug: 33770653
Change-Id: I1a6b05ea469ebbbac67d99129dd9faa457b4d17e
diff --git a/tools/ahat/src/Sort.java b/tools/ahat/src/Sort.java
index 8a3d9f2..6b93fbc 100644
--- a/tools/ahat/src/Sort.java
+++ b/tools/ahat/src/Sort.java
@@ -16,9 +16,11 @@
package com.android.ahat;
-import com.android.tools.perflib.heap.Heap;
-import com.android.tools.perflib.heap.Instance;
-
+import com.android.ahat.heapdump.AhatHeap;
+import com.android.ahat.heapdump.AhatInstance;
+import com.android.ahat.heapdump.AhatSnapshot;
+import com.android.ahat.heapdump.NativeAllocation;
+import com.android.ahat.heapdump.Site;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
@@ -38,9 +40,9 @@
* Compare instances by their instance id.
* This sorts instances from smaller id to larger id.
*/
- public static class InstanceById implements Comparator<Instance> {
+ public static class InstanceById implements Comparator<AhatInstance> {
@Override
- public int compare(Instance a, Instance b) {
+ public int compare(AhatInstance a, AhatInstance b) {
return Long.compare(a.getId(), b.getId());
}
}
@@ -51,9 +53,9 @@
* equal for the purposes of comparison.
* This sorts instances from larger retained size to smaller retained size.
*/
- public static class InstanceByTotalRetainedSize implements Comparator<Instance> {
+ public static class InstanceByTotalRetainedSize implements Comparator<AhatInstance> {
@Override
- public int compare(Instance a, Instance b) {
+ public int compare(AhatInstance a, AhatInstance b) {
return Long.compare(b.getTotalRetainedSize(), a.getTotalRetainedSize());
}
}
@@ -64,20 +66,16 @@
* equal for the purposes of comparison.
* This sorts instances from larger retained size to smaller retained size.
*/
- public static class InstanceByHeapRetainedSize implements Comparator<Instance> {
- private int mIndex;
+ public static class InstanceByHeapRetainedSize implements Comparator<AhatInstance> {
+ private AhatHeap mHeap;
- public InstanceByHeapRetainedSize(AhatSnapshot snapshot, Heap heap) {
- mIndex = snapshot.getHeapIndex(heap);
- }
-
- public InstanceByHeapRetainedSize(int heapIndex) {
- mIndex = heapIndex;
+ public InstanceByHeapRetainedSize(AhatHeap heap) {
+ mHeap = heap;
}
@Override
- public int compare(Instance a, Instance b) {
- return Long.compare(b.getRetainedSize(mIndex), a.getRetainedSize(mIndex));
+ public int compare(AhatInstance a, AhatInstance b) {
+ return Long.compare(b.getRetainedSize(mHeap), a.getRetainedSize(mHeap));
}
}
@@ -107,18 +105,18 @@
}
}
- public static Comparator<Instance> defaultInstanceCompare(AhatSnapshot snapshot) {
- List<Comparator<Instance>> comparators = new ArrayList<Comparator<Instance>>();
+ public static Comparator<AhatInstance> defaultInstanceCompare(AhatSnapshot snapshot) {
+ List<Comparator<AhatInstance>> comparators = new ArrayList<Comparator<AhatInstance>>();
// Priority goes to the app heap, if we can find one.
- Heap appHeap = snapshot.getHeap("app");
+ AhatHeap appHeap = snapshot.getHeap("app");
if (appHeap != null) {
- comparators.add(new InstanceByHeapRetainedSize(snapshot, appHeap));
+ comparators.add(new InstanceByHeapRetainedSize(appHeap));
}
// Next is by total retained size.
comparators.add(new InstanceByTotalRetainedSize());
- return new WithPriority<Instance>(comparators);
+ return new WithPriority<AhatInstance>(comparators);
}
/**
@@ -127,10 +125,10 @@
* considered equal for the purposes of comparison.
* This sorts sites from larger size to smaller size.
*/
- public static class SiteBySize implements Comparator<Site> {
- String mHeap;
+ public static class SiteByHeapSize implements Comparator<Site> {
+ AhatHeap mHeap;
- public SiteBySize(String heap) {
+ public SiteByHeapSize(AhatHeap heap) {
mHeap = heap;
}
@@ -141,6 +139,31 @@
}
/**
+ * Compare Sites by the total size of objects allocated.
+ * This sorts sites from larger size to smaller size.
+ */
+ public static class SiteByTotalSize implements Comparator<Site> {
+ @Override
+ public int compare(Site a, Site b) {
+ return Long.compare(b.getTotalSize(), a.getTotalSize());
+ }
+ }
+
+ public static Comparator<Site> defaultSiteCompare(AhatSnapshot snapshot) {
+ List<Comparator<Site>> comparators = new ArrayList<Comparator<Site>>();
+
+ // Priority goes to the app heap, if we can find one.
+ AhatHeap appHeap = snapshot.getHeap("app");
+ if (appHeap != null) {
+ comparators.add(new SiteByHeapSize(appHeap));
+ }
+
+ // Next is by total size.
+ comparators.add(new SiteByTotalSize());
+ return new WithPriority<Site>(comparators);
+ }
+
+ /**
* Compare Site.ObjectsInfo by their size.
* Different object infos with the same total retained size are considered
* equal for the purposes of comparison.
@@ -173,34 +196,34 @@
public static class ObjectsInfoByClassName implements Comparator<Site.ObjectsInfo> {
@Override
public int compare(Site.ObjectsInfo a, Site.ObjectsInfo b) {
- String aName = AhatSnapshot.getClassName(a.classObj);
- String bName = AhatSnapshot.getClassName(b.classObj);
+ String aName = a.getClassName();
+ String bName = b.getClassName();
return aName.compareTo(bName);
}
}
/**
- * Compare AhatSnapshot.NativeAllocation by heap name.
+ * Compare NativeAllocation by heap name.
* Different allocations with the same heap name are considered equal for
* the purposes of comparison.
*/
public static class NativeAllocationByHeapName
- implements Comparator<InstanceUtils.NativeAllocation> {
+ implements Comparator<NativeAllocation> {
@Override
- public int compare(InstanceUtils.NativeAllocation a, InstanceUtils.NativeAllocation b) {
+ public int compare(NativeAllocation a, NativeAllocation b) {
return a.heap.getName().compareTo(b.heap.getName());
}
}
/**
- * Compare InstanceUtils.NativeAllocation by their size.
+ * Compare NativeAllocation by their size.
* Different allocations with the same size are considered equal for the
* purposes of comparison.
* This sorts allocations from larger size to smaller size.
*/
- public static class NativeAllocationBySize implements Comparator<InstanceUtils.NativeAllocation> {
+ public static class NativeAllocationBySize implements Comparator<NativeAllocation> {
@Override
- public int compare(InstanceUtils.NativeAllocation a, InstanceUtils.NativeAllocation b) {
+ public int compare(NativeAllocation a, NativeAllocation b) {
return Long.compare(b.size, a.size);
}
}