JVM gc roots有什么
在Java虚拟机(JVM)中,GC Roots(垃圾回收根)是垃圾收集器(Garbage Collector)用来判断一个对象是否存活的起始点集合。
JVM的垃圾回收采用的是“可达性分析”(Reachability Analysis)算法。这个算法的基本思路是:从一系列被称为“GC Roots”的根对象开始,向下搜索,所有能够从GC Roots直接或间接访问到的对象都被认为是“存活”的,反之,如果一个对象不能从任何一个GC Root到达,那么它就被判定为“垃圾”,可以被回收。
你可以把整个JVM内存中的对象想象成一个巨大的关系网络。GC Roots就是这个网络中几个“永远不会被拔掉”的初始节点。垃圾回收的过程,就是从这些初始节点出发,沿着引用链(就像网络中的连接线),把所有能摸到的节点都标记为“存活”。那些最终没有被标记到的,就是与初始节点“失联”的,也就是可以被清理的垃圾。
那么,具体作为GC Roots的对象主要包括以下几种:
-
虚拟机栈(栈帧中的本地变量表)中引用的对象
- 解释:当前正在执行的方法中的所有本地变量。当一个方法被调用时,它会创建一个栈帧,栈帧中包含了方法的参数、局部变量等。如果一个局部变量引用了一个堆中的对象,那么这个对象就是存活的,不能被回收。
-
方法区中类静态属性引用的对象
- 解释:由类的静态字段(static variables)引用的对象。这些变量属于类本身,而不是类的某个实例,它们的生命周期与类加载的生命周期相同。只要类没有被卸载,这些静态变量引用的对象就会一直存活。
-
方法区中常量引用的对象
- 解释:例如,字符串常量池(String Table)里的引用。如果一个字符串常量被引用,那么它背后的String对象也是存活的。
-
本地方法栈中JNI(即通常所说的Native方法)引用的对象
- 解释:当Java代码通过JNI(Java Native Interface)调用本地代码(如C或C++代码)时,本地代码可能会创建或持有对Java对象的引用。为了保证本地代码的正常工作,这些被JNI引用的Java对象也必须被视为存活对象,不能被回收。
-
Java虚拟机内部的引用
- 解释:这些是JVM自身运行所必需的对象,比如一些核心的类加载器、系统类、异常对象等。它们是JVM正常工作的基础,显然不能被回收。
-
被同步锁(synchronized关键字)持有的对象
- 解释:在同步代码块中,被用作锁的对象(即
synchronized(obj)中的obj)在锁被持有的期间是不能被回收的,否则可能导致多线程同步问题。
- 解释:在同步代码块中,被用作锁的对象(即
-
反映Java虚拟机内部情况的JMXBean、JVMTI中注册的回调、本地代码缓存等。
- 解释:这是一些更偏向底层的、用于JVM监控和调试的内部对象,它们也需要作为GC Roots来保证自身的存活。