use of com.squareup.haha.perflib.RootObj in project leakcanary by square.
the class HeapAnalyzer method deduplicateGcRoots.
/**
* Pruning duplicates reduces memory pressure from hprof bloat added in Marshmallow.
*/
void deduplicateGcRoots(Snapshot snapshot) {
// THashMap has a smaller memory footprint than HashMap.
final THashMap<String, RootObj> uniqueRootMap = new THashMap<>();
final Collection<RootObj> gcRoots = snapshot.getGCRoots();
for (RootObj root : gcRoots) {
String key = generateRootKey(root);
if (!uniqueRootMap.containsKey(key)) {
uniqueRootMap.put(key, root);
}
}
// Repopulate snapshot with unique GC roots.
gcRoots.clear();
uniqueRootMap.forEach(new TObjectProcedure<String>() {
@Override
public boolean execute(String key) {
return gcRoots.add(uniqueRootMap.get(key));
}
});
}
use of com.squareup.haha.perflib.RootObj in project leakcanary by square.
the class ShortestPathFinder method visitRootObj.
private void visitRootObj(LeakNode node) {
RootObj rootObj = (RootObj) node.instance;
Instance child = rootObj.getReferredInstance();
if (rootObj.getRootType() == RootType.JAVA_LOCAL) {
Instance holder = HahaSpy.allocatingThread(rootObj);
// We switch the parent node with the thread instance that holds
// the local reference.
Exclusion exclusion = null;
if (node.exclusion != null) {
exclusion = node.exclusion;
}
LeakNode parent = new LeakNode(null, holder, null, null, null);
enqueue(exclusion, parent, child, "<Java Local>", LOCAL);
} else {
enqueue(null, node, child, null, null);
}
}
use of com.squareup.haha.perflib.RootObj in project leakcanary by square.
the class ShortestPathFinder method enqueueGcRoots.
private void enqueueGcRoots(Snapshot snapshot) {
for (RootObj rootObj : snapshot.getGCRoots()) {
switch(rootObj.getRootType()) {
case JAVA_LOCAL:
Instance thread = HahaSpy.allocatingThread(rootObj);
String threadName = threadName(thread);
Exclusion params = excludedRefs.threadNames.get(threadName);
if (params == null || !params.alwaysExclude) {
enqueue(params, null, rootObj, null, null);
}
break;
case INTERNED_STRING:
case DEBUGGER:
case INVALID_TYPE:
// An object that is unreachable from any other root, but not a root itself.
case UNREACHABLE:
case UNKNOWN:
// An object that is in a queue, waiting for a finalizer to run.
case FINALIZING:
break;
case SYSTEM_CLASS:
case VM_INTERNAL:
// A local variable in native code.
case NATIVE_LOCAL:
// A global variable in native code.
case NATIVE_STATIC:
// An object that was referenced from an active thread block.
case THREAD_BLOCK:
// Everything that called the wait() or notify() methods, or that is synchronized.
case BUSY_MONITOR:
case NATIVE_MONITOR:
case REFERENCE_CLEANUP:
// Input or output parameters in native code.
case NATIVE_STACK:
case JAVA_STATIC:
enqueue(null, null, rootObj, null, null);
break;
default:
throw new UnsupportedOperationException("Unknown root type:" + rootObj.getRootType());
}
}
}
use of com.squareup.haha.perflib.RootObj in project leakcanary by square.
the class HeapAnalyzerTest method ensureUniqueRoots.
@Test
public void ensureUniqueRoots() {
Snapshot snapshot = createSnapshot(DUP_ROOTS);
heapAnalyzer.deduplicateGcRoots(snapshot);
Collection<RootObj> uniqueRoots = snapshot.getGCRoots();
assertThat(uniqueRoots).hasSize(4);
List<Long> rootIds = new ArrayList<>();
for (RootObj root : uniqueRoots) {
rootIds.add(root.getId());
}
Collections.sort(rootIds);
// 3 appears twice because even though two RootObjs have the same id, they're different types.
assertThat(rootIds).containsExactly(3L, 3L, 5L, 6L);
}
use of com.squareup.haha.perflib.RootObj in project leakcanary by square.
the class HeapAnalyzer method isIgnoredDominator.
private boolean isIgnoredDominator(Instance dominator, Instance instance) {
boolean foundNativeRoot = false;
while (true) {
Instance immediateDominator = instance.getImmediateDominator();
if (immediateDominator instanceof RootObj && ((RootObj) immediateDominator).getRootType() == RootType.UNKNOWN) {
// Ignore native roots
instance = instance.getNextInstanceToGcRoot();
foundNativeRoot = true;
} else {
instance = immediateDominator;
}
if (instance == null) {
return false;
}
if (instance == dominator) {
return foundNativeRoot;
}
}
}
Aggregations