LeakTraceElement(LeakReference reference, Holder holder, List<String> classHierarchy, String extra, Exclusion exclusion, List<LeakReference> leakReferences) { this.reference = reference; this.referenceName = reference == null ? null : reference.getDisplayName(); this.type = reference == null ? null : reference.type; this.holder = holder; this.classHierarchy = Collections.unmodifiableList(new ArrayList<>(classHierarchy)); this.className = classHierarchy.get(0); this.extra = extra; this.exclusion = exclusion; this.fieldReferences = unmodifiableList(new ArrayList<>(leakReferences)); List<String> stringFields = new ArrayList<>(); for (LeakReference leakReference : leakReferences) { stringFields.add(leakReference.toString()); } fields = Collections.unmodifiableList(stringFields); }
@Override public String toString() { switch (type) { case ARRAY_ENTRY: case INSTANCE_FIELD: return getDisplayName() + " = " + value; case STATIC_FIELD: return "static " + getDisplayName() + " = " + value; case LOCAL: return getDisplayName(); default: throw new IllegalStateException( "Unexpected type " + type + " name = " + name + " value = " + value); } } }
private void visitArrayInstance(LeakNode node) { ArrayInstance arrayInstance = (ArrayInstance) node.instance; Type arrayType = arrayInstance.getArrayType(); if (arrayType == Type.OBJECT) { Object[] values = arrayInstance.getValues(); for (int i = 0; i < values.length; i++) { Instance child = (Instance) values[i]; String name = Integer.toString(i); String value = child == null ? "null" : child.toString(); enqueue(null, node, child, new LeakReference(ARRAY_ENTRY, name, value)); } } }
public String toString(boolean maybeLeakCause) { String string = ""; if (reference != null && reference.type == STATIC_FIELD) { string += "static "; } if (holder == ARRAY || holder == THREAD) { string += holder.name().toLowerCase(US) + " "; } string += getSimpleClassName(); if (reference != null) { String referenceName = reference.getDisplayName(); if (maybeLeakCause) { referenceName = "!(" + referenceName + ")!"; } string += "." + referenceName; } if (extra != null) { string += " " + extra; } if (exclusion != null) { string += " , matching exclusion " + exclusion.matching; } return string; }
boolean visit = true; String fieldValue = entry.getValue() == null ? "null" : entry.getValue().toString(); LeakReference leakReference = new LeakReference(STATIC_FIELD, fieldName, fieldValue); if (ignoredStaticFields != null) { Exclusion params = ignoredStaticFields.get(fieldName);
String referenceName = element.reference.getDisplayName().replaceAll("<", "<") .replaceAll(">", ">");
String name = entry.getKey().getName(); String stringValue = valueAsString(entry.getValue()); leakReferences.add(new LeakReference(STATIC_FIELD, name, stringValue)); String name = Integer.toString(i); String stringValue = valueAsString(values[i]); leakReferences.add(new LeakReference(ARRAY_ENTRY, name, stringValue)); String name = entry.getKey().getName(); String stringValue = valueAsString(entry.getValue()); leakReferences.add(new LeakReference(STATIC_FIELD, name, stringValue)); String name = field.getField().getName(); String stringValue = valueAsString(field.getValue()); leakReferences.add(new LeakReference(INSTANCE_FIELD, name, stringValue));
enqueue(fieldExclusion, node, child, new LeakReference(INSTANCE_FIELD, fieldName, value));
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); enqueue(exclusion, parent, child, new LeakReference(LOCAL, null, null)); } else { enqueue(null, node, child, null); } }