【記憶體優化】 MAT 看記憶體 Native Stack 找不到真正的引用
用Eclipse Memory Analyzer(也就是MAT) 優化記憶體時遇到下面一種情況。
每次操作都會導致AudioDecoderTrack這個類增加,但是又看不到具體的引用。能看到的只有一個Native Stack,而且前面也不是引用的箭頭,而是一個小黃點。
這是為什麼呢?小黃點代表這個類是一個GC Root,GC Root 具體的概念及產生情況如下:
Garbage Collection Roots
A garbage collection root is an object that is accessible from outside the heap. The following reasons make an object a GC root:System Class
Class loaded by bootstrap/system class loader. For example, everything from the rt.jar like java.util.* .
JNI Local
Local variable in native code, such as user defined JNI code or JVM internal code.
JNI Global
Global variable in native code, such as user defined JNI code or JVM internal code.
Thread Block
Object referred to from a currently active thread block.
Thread
A started, but not stopped, thread.
Busy Monitor
Everything that has called wait() or notify() or that is synchronized. For example, by calling synchronized(Object) or by entering a synchronized method. Static method means class, non-static method means object.
Java Local
Local variable. For example, input parameters or locally created objects of methods that are still in the stack of a thread.
Native Stack
In or out parameters in native code, such as user defined JNI code or JVM internal code. This is often the case as many methods have native parts and the objects handled as method parameters become GC roots. For example, parameters used for file/network I/O methods or reflection.
Finalizable
An object which is in a queue awaiting its finalizer to be run.
Unfinalized
An object which has a finalize method, but has not been finalized and is not yet on the finalizer queue.
Unreachable
An object which is unreachable from any other root, but has been marked as a root by MAT to retain objects which otherwise would not be included in the analysis.
Java Stack Frame
A Java stack frame, holding local variables. Only generated when the dump is parsed with the preference set to treat Java stack frames as objects.
Unknown
An object of unknown root type. Some dumps, such as IBM Portable Heap Dump files, do not have root information. For these dumps the MAT parser marks objects which are have no inbound references or are unreachable from any other root as roots of this type. This ensures that MAT retains all the objects in the dump.
可以看到Native Stack產生原因:In or out parameters in native code, such as user defined JNI code or JVM internal code.因此,大致可以確定是因為jni持有AudioDecoderTrack的引用導致的記憶體洩露。
最終定位到是jni建立了GlobalRef,但是沒有Delete導致的。修改完之後無論多少次操作都只會有一個AudioDecoderTrack