一 背景
最近面试,被问到常见的GC Root 是什么?
我有个感觉,关于JVM的问题,自己看过深入理解JVM 的书,也排查过线上的OOM的问题,用过MAT分析dump。
总是觉得含含糊糊,不是那么有信心。
面试也是我们一个学习的机会。补充下:
二 整理:
可达性:基本思想就是通过一系列的GC Root对象作为起点,从这些节点开始向下搜索,节点所走过的路称之为引用链,当一个对象没有被任何引用链链接的话,这个对象就是不可用的。
先看书上的:GC root对象
- 虚拟机栈(栈帧中的本地变量表)中引用的对象;
- 方法区中类静态属性引用的对象;
- 方法区中常量引用的对象;
- 本地方法栈中JNI(即一般说的Native方法)引用的对象
如果参照eclipse的文档,更详细:
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.
哪些不会被回收?
- Java Local 本地变量表,如果执行到某个方法的时候,进行了垃圾回收,那么方法里面的局部变量引用的对象是不能被回收的
- 一个活着的线程里面的对象肯定不能被回收。
- System Class 被系统classloader 加载的类,引用的对象肯定不能回收。比如:rt.jar 里面的一些对象。
- Monitor Used-用于同步监控的对象(回收加锁就异常了)。
有个demo:
public class MemoryDemo {
/**
* @param args
*/
public static void main(String[] args) throws InterruptedException {
Runtime r = Runtime.getRuntime();
long mem1, mem2;
String someints[] = new String[10000];
System.out.println("Total memory is: " + r.totalMemory()+",maxmemory:"+ r.maxMemory());
mem1 = r.freeMemory();
System.out.println("Initial free memory: " + mem1);
r.gc();
mem1 = r.freeMemory();
System.out.println("Free memory after garbage collection: " + mem1);
for (int i = 0; i < 10000; i++)
someints[i] = i+""; // allocate integers
mem2 = r.freeMemory();
System.out.println("Free memory after allocation: " +r.freeMemory() +",total:"+ +r.totalMemory()+",maxmemory:"+r.maxMemory());
System.out.println("Memory used by allocation: " + (mem1 - mem2));
// discard Integers
for (int i = 0; i < 10000; i++)
someints[i] = null;
r.gc(); // request garbage collection
Thread.sleep(100);
mem2 = r.freeMemory();
System.out.println("Free memory after collecting discarded String: " + mem2);
}
}
帮助理解。
maxMemory()这个方法返回的是java虚拟机(这个进程)能构从操作系统那里最大内存。
totalMemory()这个方法返回的是java虚拟机现在已经从操作系统那里申请的内存大小。
freeMemory()空闲的内存。