<lambda>null1package shark 2 3 import shark.ObjectInspectors.KEYED_WEAK_REFERENCE 4 import shark.internal.KeyedWeakReferenceMirror 5 6 /** 7 * Finds all objects tracked by a KeyedWeakReference, ie all objects that were passed to 8 * ObjectWatcher.watch. 9 */ 10 object KeyedWeakReferenceFinder : LeakingObjectFinder { 11 12 override fun findLeakingObjectIds(graph: HeapGraph): Set<Long> = 13 findKeyedWeakReferences(graph) 14 .filter { it.hasReferent && it.isRetained } 15 .map { it.referent.value } 16 .toSet() 17 18 fun heapDumpUptimeMillis(graph: HeapGraph): Long? { 19 return graph.context.getOrPut("heapDumpUptimeMillis") { 20 val keyedWeakReferenceClass = graph.findClassByName("leakcanary.KeyedWeakReference") 21 val heapDumpUptimeMillis = if (keyedWeakReferenceClass == null) { 22 null 23 } else { 24 keyedWeakReferenceClass["heapDumpUptimeMillis"]?.value?.asLong 25 } 26 if (heapDumpUptimeMillis == null) { 27 SharkLog.d { 28 "leakcanary.KeyedWeakReference.heapDumpUptimeMillis field not found" 29 } 30 } 31 heapDumpUptimeMillis 32 } 33 } 34 35 internal fun findKeyedWeakReferences(graph: HeapGraph): List<KeyedWeakReferenceMirror> { 36 return graph.context.getOrPut(KEYED_WEAK_REFERENCE.name) { 37 val keyedWeakReferenceClass = graph.findClassByName("leakcanary.KeyedWeakReference") 38 39 val keyedWeakReferenceClassId = keyedWeakReferenceClass?.objectId ?: 0 40 val legacyKeyedWeakReferenceClassId = 41 graph.findClassByName("com.squareup.leakcanary.KeyedWeakReference")?.objectId ?: 0 42 43 val heapDumpUptimeMillis = heapDumpUptimeMillis(graph) 44 45 val addedToContext: List<KeyedWeakReferenceMirror> = graph.instances 46 .filter { instance -> 47 instance.instanceClassId == keyedWeakReferenceClassId || instance.instanceClassId == legacyKeyedWeakReferenceClassId 48 } 49 .map { 50 KeyedWeakReferenceMirror.fromInstance( 51 it, heapDumpUptimeMillis 52 ) 53 } 54 .toList() 55 graph.context[KEYED_WEAK_REFERENCE.name] = addedToContext 56 addedToContext 57 } 58 } 59 }