use of com.squareup.haha.perflib.Instance in project leakcanary by square.
the class ShortestPathFinder method visitClassObj.
private void visitClassObj(LeakNode node) {
ClassObj classObj = (ClassObj) node.instance;
Map<String, Exclusion> ignoredStaticFields = excludedRefs.staticFieldNameByClassName.get(classObj.getClassName());
for (Map.Entry<Field, Object> entry : classObj.getStaticFieldValues().entrySet()) {
Field field = entry.getKey();
if (field.getType() != Type.OBJECT) {
continue;
}
String fieldName = field.getName();
if (fieldName.equals("$staticOverhead")) {
continue;
}
Instance child = (Instance) entry.getValue();
boolean visit = true;
if (ignoredStaticFields != null) {
Exclusion params = ignoredStaticFields.get(fieldName);
if (params != null) {
visit = false;
if (!params.alwaysExclude) {
enqueue(params, node, child, fieldName, STATIC_FIELD);
}
}
}
if (visit) {
enqueue(null, node, child, fieldName, STATIC_FIELD);
}
}
}
use of com.squareup.haha.perflib.Instance in project leakcanary by square.
the class HahaHelper method asString.
static String asString(Object stringObject) {
Instance instance = (Instance) stringObject;
List<ClassInstance.FieldValue> values = classInstanceValues(instance);
Integer count = fieldValue(values, "count");
Object value = fieldValue(values, "value");
Integer offset;
ArrayInstance charArray;
if (isCharArray(value)) {
charArray = (ArrayInstance) value;
offset = 0;
// https://android-review.googlesource.com/#/c/83611/
if (hasField(values, "offset")) {
offset = fieldValue(values, "offset");
}
} else {
// In M preview 2, the underlying char buffer resides in the heap with ID equaling the
// String's ID + 16.
// https://android-review.googlesource.com/#/c/160380/2/android/src/com/android/tools/idea/
// editors/hprof/descriptors/InstanceFieldDescriptorImpl.java
// This workaround is only needed for M preview 2, as it has been fixed on the hprof
// generation end by reintroducing a virtual "value" variable.
// https://android.googlesource.com/platform/art/+/master/runtime/hprof/hprof.cc#1242
Heap heap = instance.getHeap();
Instance inlineInstance = heap.getInstance(instance.getId() + 16);
if (isCharArray(inlineInstance)) {
charArray = (ArrayInstance) inlineInstance;
offset = 0;
} else {
throw new UnsupportedOperationException("Could not find char array in " + instance);
}
}
checkNotNull(count, "count");
checkNotNull(charArray, "charArray");
checkNotNull(offset, "offset");
if (count == 0) {
return "";
}
char[] chars = charArray.asCharArray(offset, count);
return new String(chars);
}
use of com.squareup.haha.perflib.Instance in project leakcanary by square.
the class HeapAnalyzer method checkForLeak.
/**
* Searches the heap dump for a {@link KeyedWeakReference} instance with the corresponding key,
* and then computes the shortest strong reference path from that instance to the GC roots.
*/
public AnalysisResult checkForLeak(File heapDumpFile, String referenceKey) {
long analysisStartNanoTime = System.nanoTime();
if (!heapDumpFile.exists()) {
Exception exception = new IllegalArgumentException("File does not exist: " + heapDumpFile);
return failure(exception, since(analysisStartNanoTime));
}
try {
HprofBuffer buffer = new MemoryMappedFileBuffer(heapDumpFile);
HprofParser parser = new HprofParser(buffer);
Snapshot snapshot = parser.parse();
deduplicateGcRoots(snapshot);
Instance leakingRef = findLeakingReference(referenceKey, snapshot);
// False alarm, weak reference was cleared in between key check and heap dump.
if (leakingRef == null) {
return noLeak(since(analysisStartNanoTime));
}
return findLeakTrace(analysisStartNanoTime, snapshot, leakingRef);
} catch (Throwable e) {
return failure(e, since(analysisStartNanoTime));
}
}
Aggregations