main

square/leakcanary

Last updated at: 29/12/2023 09:38

GcRoot.kt

TLDR

The GcRoot class represents different types of garbage collection roots in a heap dump. It contains subclasses that represent specific types of garbage collection roots, such as unknown roots, JNI globals, JNI locals, Java locals, native stacks, etc.

Classes

GcRoot

The GcRoot class is the base class for all types of garbage collection roots. It is a sealed class, meaning that it can only be subclassed within its own file. It contains an abstract property id that represents the object ID of the object that the garbage collection root references.

Unknown

The Unknown class is a subclass of GcRoot and represents an unknown garbage collection root. It has a constructor that takes an id parameter, which is the object ID of the referenced object.

JniGlobal

The JniGlobal class is a subclass of GcRoot and represents a global variable in native code. It has a constructor that takes an id parameter, which is the object ID of the referenced object, and a jniGlobalRefId parameter, which represents the ID of the JNI global reference.

JniLocal

The JniLocal class is a subclass of GcRoot and represents a local variable in native code. It has a constructor that takes an id parameter, which is the object ID of the referenced object, a threadSerialNumber parameter, which corresponds to the ThreadObject.threadSerialNumber, and a frameNumber parameter, which represents the frame number in the stack trace.

JavaFrame

The JavaFrame class is a subclass of GcRoot and represents a Java local variable. It has a constructor that takes an id parameter, which is the object ID of the referenced object, a threadSerialNumber parameter, which corresponds to the ThreadObject.threadSerialNumber, and a frameNumber parameter, which represents the frame number in the stack trace.

NativeStack

The NativeStack class is a subclass of GcRoot and represents input or output parameters in native code. It has a constructor that takes an id parameter, which is the object ID of the referenced object, and a threadSerialNumber parameter, which corresponds to the ThreadObject.threadSerialNumber.

StickyClass

The StickyClass class is a subclass of GcRoot and represents a system class. It has a constructor that takes an id parameter, which is the object ID of the referenced object.

ThreadBlock

The ThreadBlock class is a subclass of GcRoot and represents a thread block. It has a constructor that takes an id parameter, which is the object ID of the referenced object, and a threadSerialNumber parameter, which corresponds to the ThreadObject.threadSerialNumber.

MonitorUsed

The MonitorUsed class is a subclass of GcRoot and represents objects that called the wait() or notify() methods, or that are synchronized. It has a constructor that takes an id parameter, which is the object ID of the referenced object.

ThreadObject

The ThreadObject class is a subclass of GcRoot and represents a thread. It has a constructor that takes an id parameter, which is the object ID of the referenced object, a threadSerialNumber parameter, which corresponds to the ThreadObject.threadSerialNumber, and a stackTraceSerialNumber parameter.

ReferenceCleanup

The ReferenceCleanup class is a subclass of GcRoot and represents an unknown type of garbage collection root. It has a constructor that takes an id parameter, which is the object ID of the referenced object.

VmInternal

The VmInternal class is a subclass of GcRoot and represents an unknown type of garbage collection root. It has a constructor that takes an id parameter, which is the object ID of the referenced object.

JniMonitor

The JniMonitor class is a subclass of GcRoot and represents a JNI monitor. It has a constructor that takes an id parameter, which is the object ID of the referenced object, a stackTraceSerialNumber parameter, and a stackDepth parameter.

InternedString

The InternedString class is a subclass of GcRoot and represents an interned string. It has a constructor that takes an id parameter, which is the object ID of the referenced object.

Finalizing

The Finalizing class is a subclass of GcRoot and represents an object that is in a queue, waiting for a finalizer to run. It has a constructor that takes an id parameter, which is the object ID of the referenced object.

Debugger

The Debugger class is a subclass of GcRoot and represents an object held by a connected debugger. It has a constructor that takes an id parameter, which is the object ID of the referenced object.

Unreachable

The Unreachable class is a subclass of GcRoot and represents an object that is unreachable from any other root, but not a root itself. It has a constructor that takes an id parameter, which is the object ID of the referenced object.

package shark

/**
 * A GcRoot as identified by [HprofRecord.HeapDumpRecord.GcRootRecord] in the heap dump.
 */
sealed class GcRoot {

  /**
   * The object id of the object that this gc root references.
   */
  abstract val id: Long

  /**
   * An unknown gc root.
   */
  class Unknown(override val id: Long) : GcRoot()

  /**
   * A global variable in native code.
   */
  class JniGlobal(
    override val id: Long,
    val jniGlobalRefId: Long
  ) : GcRoot()

  /**
   * A local variable in native code.
   */
  class JniLocal(
    override val id: Long,
    /** Corresponds to [ThreadObject.threadSerialNumber] */
    val threadSerialNumber: Int,
    /**
     * frame number in stack trace (-1 for empty)
     */
    val frameNumber: Int
  ) : GcRoot()

  /**
   * A java local variable
   */
  class JavaFrame(
    override val id: Long,
    /** Corresponds to [ThreadObject.threadSerialNumber] */
    val threadSerialNumber: Int,
    /**
     * frame number in stack trace (-1 for empty)
     */
    val frameNumber: Int
  ) : GcRoot()

  /**
   * Input or output parameters in native code
   */
  class NativeStack(
    override val id: Long,
    /**
     * Corresponds to [ThreadObject.threadSerialNumber]
     * Note: the corresponding thread is sometimes not found, see:
     * https://issuetracker.google.com/issues/122713143
     */
    val threadSerialNumber: Int
  ) : GcRoot()

  /**
   * A system class
   */
  class StickyClass(override val id: Long) : GcRoot()

  class ThreadBlock(
    override val id: Long,
    /** Corresponds to [ThreadObject.threadSerialNumber] */
    val threadSerialNumber: Int
  ) : GcRoot()

  /**
   * Everything that called the wait() or notify() methods, or
   * that is synchronized.
   */
  class MonitorUsed(override val id: Long) : GcRoot()

  /**
   * A thread.
   *
   * Added at https://android.googlesource.com/platform/tools/base/+/c0f0d528c155cab32e372dac77370569a386245c
   */
  class ThreadObject(
    override val id: Long,
    val threadSerialNumber: Int,
    val stackTraceSerialNumber: Int
  ) : GcRoot()

  /**
   * It's unclear what this is, documentation welcome.
   */
  class ReferenceCleanup(override val id: Long) : GcRoot()

  /**
   * It's unclear what this is, documentation welcome.
   */
  class VmInternal(override val id: Long) : GcRoot()

  /**
   * It's unclear what this is, documentation welcome.
   */
  class JniMonitor(
    override val id: Long,
    val stackTraceSerialNumber: Int,
    val stackDepth: Int
  ) : GcRoot()

  /**
   * An interned string, see [java.lang.String.intern].
   */
  class InternedString(override val id: Long) : GcRoot()

  /**
   * An object that is in a queue, waiting for a finalizer to run.
   */
  class Finalizing(override val id: Long) : GcRoot()

  /**
   * An object held by a connected debugger
   */
  class Debugger(override val id: Long) : GcRoot()

  /**
   * An object that is unreachable from any other root, but not a root itself.
   */
  class Unreachable(override val id: Long) : GcRoot()
}