JNI Reference Diagnostics

Capture a bounded, redacted Android heap graph rooted at JNI global, local, and monitor references.

The Android JNI Reference Diagnostics suite exposes the read-scoped jni_references.capture_graph tool for investigating Java objects retained through JNI roots.

Install

The aggregate ai.ansight:ansight-android package includes the suite. For a narrow Debug-only integration:

dependencies {
    debugImplementation("ai.ansight:ansight-tools-jnireferencediagnostics-android:1.3.0-preview.10")
}

Register and Bound the Suite

import ai.ansight.runtime.AnsightOptions
import ai.ansight.tools.jnireferencediagnostics.withJniReferenceDiagnosticsTools

val options = AnsightOptions.createBuilder()
    .withJniReferenceDiagnosticsTools {
        maximumGraphNodes(4096)
        maximumGraphEdges(8192)
        maximumGraphDepth(12)
    }
    .withReadOnlyToolAccess()
    .build()

Configured maxima default to 2,048 nodes, 4,096 edges, and depth 8 and are clamped to 8,192 nodes, 16,384 edges, and depth 16. An individual tool call defaults to the smaller 512 nodes, 1,024 edges, and depth 4 and can request any value up to the configured maxima.

{
  "toolId": "jni_references.capture_graph",
  "arguments": {
    "maxNodes": 1024,
    "maxEdges": 2048,
    "maxDepth": 6
  }
}

Result and Redaction

The tool asks ART for a temporary HPROF snapshot, indexes it with Shark, and walks only objects reachable from JNI global, local, or monitor roots. The result includes:

  • capture-local opaque root and object ids
  • root kind and bounded local/monitor metadata
  • class names, object kinds, shallow sizes, and depth
  • field or array reference edges
  • capture limits, counts, duration, HPROF size, and truncation reasons

It deliberately omits raw heap ids, JNI handle addresses, primitive values, strings, and field values. Opaque ids are valid only for the returned capture.

Availability and Cost

Tool discovery reports current runtime availability. The tool requires an initialized Android Application; an unavailable catalog entry reports android_application_unavailable and the required state rather than waiting for invocation to fail.

Heap dumping briefly pauses the app and indexing uses additional memory. Capture is serialized, intended only for explicit development diagnostics, and deletes the temporary HPROF file after graph construction. Do not call it during performance measurements or expose it outside a trusted development build.

Use Performance Telemetry with withJniReferenceCountTracking() for a lightweight trend. Invoke this tool only when the trend warrants a bounded object-graph investigation.