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.