KeyedWeakReferenceMirror.kt
TLDR
This file contains the implementation of the KeyedWeakReferenceMirror
class, which represents a mirrored version of a weak reference in the heap dump.
Classes
KeyedWeakReferenceMirror
The KeyedWeakReferenceMirror
class represents a mirrored version of a weak reference in the heap dump. It has the following properties:
-
referent
- The reference to the object being referred to. -
key
- The key associated with the weak reference. -
description
- The description of the weak reference. (Note: In pre-2.0 heap dumps, this field is named "name"). -
watchDurationMillis
- The duration for which the weak reference has been watched. (Note: This field is null in pre-2.0 alpha 3 heap dumps). -
retainedDurationMillis
- The duration for which the referent object has been retained. (Note: This field is null in pre-2.0 alpha 3 heap dumps, and -1 if the instance is not retained).
The KeyedWeakReferenceMirror
class also has the following methods:
-
hasReferent
- Checks if the weak reference has a referent object. -
isRetained
- Checks if the referent object is retained.
Note: This class is in the shark.internal
package.
package shark.internal
import shark.HeapObject.HeapInstance
import shark.ValueHolder
import shark.ValueHolder.ReferenceHolder
internal class KeyedWeakReferenceMirror(
val referent: ReferenceHolder,
val key: String,
// The name field does not exist in pre 1.0 heap dumps.
val description: String,
// null in pre 2.0 alpha 3 heap dumps
val watchDurationMillis: Long?,
// null in pre 2.0 alpha 3 heap dumps, -1 if the instance is not retained.
val retainedDurationMillis: Long?
) {
val hasReferent = referent.value != ValueHolder.NULL_REFERENCE
val isRetained = retainedDurationMillis == null || retainedDurationMillis != -1L
companion object {
private const val UNKNOWN_LEGACY = "Unknown (legacy)"
fun fromInstance(
weakRef: HeapInstance,
// Null for pre 2.0 alpha 3 heap dumps
heapDumpUptimeMillis: Long?
): KeyedWeakReferenceMirror {
val keyWeakRefClassName = weakRef.instanceClassName
val watchDurationMillis = if (heapDumpUptimeMillis != null) {
heapDumpUptimeMillis - weakRef[keyWeakRefClassName, "watchUptimeMillis"]!!.value.asLong!!
} else {
null
}
val retainedDurationMillis = if (heapDumpUptimeMillis != null) {
val retainedUptimeMillis =
weakRef[keyWeakRefClassName, "retainedUptimeMillis"]!!.value.asLong!!
if (retainedUptimeMillis == -1L) -1L else heapDumpUptimeMillis - retainedUptimeMillis
} else {
null
}
val keyString = weakRef[keyWeakRefClassName, "key"]!!.value.readAsJavaString()!!
// Changed from name to description after 2.0
val description = (weakRef[keyWeakRefClassName, "description"]
?: weakRef[keyWeakRefClassName, "name"])?.value?.readAsJavaString() ?: UNKNOWN_LEGACY
return KeyedWeakReferenceMirror(
watchDurationMillis = watchDurationMillis,
retainedDurationMillis = retainedDurationMillis,
referent = weakRef["java.lang.ref.Reference", "referent"]!!.value.holder as ReferenceHolder,
key = keyString,
description = description
)
}
}
}