DumpReferenceTables()
Dumps JNI local/global reference tables to logcat.
Read time 2 minutesLast updated 10 days ago
Definition
- Type: Method
- Namespace: UnityEngine
- Assembly: UnityEngine.AndroidJNIModule
public static bool DumpReferenceTables()
Returns
Type | Description |
|---|---|
| bool | Returns true if |
Remarks
Used to diagnose JNI reference leaks and other reference-table corruption.
Note: This function attempts to invoke the undocumented method. If that method is unavailable, AndroidJNI.DumpReferenceTables has no effect.
android.os.Debug.dumpReferenceTables()Each AndroidJavaObject instance creates a global JNI reference, which remains until the object is explicitly disposed or collected by the C# garbage collector. Failing to dispose an AndroidJavaObject can lead to if the process reaches the maximum number of allowed JNI references.
java.lang.OutOfMemoryErrorCall AndroidJNI.DumpReferenceTables before and after the code which you want to test, and compare two outputs to determine if you're leaking.
Additional Resources: Local and global JNI references.
using UnityEngine;using UnityEngine.Android;public class Sample : MonoBehaviour{ void TestLeaks() { using var motionEventClass = new AndroidJavaClass("android.view.MotionEvent"); AndroidJNI.DumpReferenceTables(); for (int i = 0; i < 100; i++) { var window = AndroidApplication.currentActivity.Call<AndroidJavaObject>("getWindow"); // Do something with window // If you'll fail to call Dispose(), jni reference will be kept alive until C# garbage collector collects 'window' object (which might not happen soon) // There's a limited amount of max jni references you can have, it depends on the Android version, it's always better to Dispose or use 'using' keyword to release jni reference. // window.Dispose(); } AndroidJNI.DumpReferenceTables(); } private void OnGUI() { GUILayout.Space(100); if (GUILayout.Button("TestLeaks", GUILayout.Height(200), GUILayout.Width(Screen.width))) TestLeaks(); }}
The sample above will produce the following log:
--- reference table dump ---
local reference table dump:
Last 1 entries (of 1):
0: 0x242c298 java.lang.Class<com.unity3d.player.ReflectionHelper>
Summary:
1 of java.lang.Class
monitors reference table dump:
(empty)
global reference table dump:
Last 10 entries (of 744):
743: 0x6faef540 java.lang.Class<com.android.internal.policy.PhoneWindow>
742: 0x2348060 com.android.internal.policy.PhoneWindow
741: 0x6faef540 java.lang.Class<com.android.internal.policy.PhoneWindow>
740: 0x2348060 com.android.internal.policy.PhoneWindow
739: 0x6faef540 java.lang.Class<com.android.internal.policy.PhoneWindow>
738: 0x2348060 com.android.internal.policy.PhoneWindow
737: 0x6faef540 java.lang.Class<com.android.internal.policy.PhoneWindow>
736: 0x2348060 com.android.internal.policy.PhoneWindow
735: 0x6faef540 java.lang.Class<com.android.internal.policy.PhoneWindow>
734: 0x2348060 com.android.internal.policy.PhoneWindow.
Notice global reference table dump contains a lot of instances, to fix the leak, you need to properly dispose object by calling method.
com.android.internal.policy.PhoneWindowwindowDispose