java对象什么时候被垃圾回收?
简单一句就是:如果一个或多个对象没有任何的引用指向它了,那么这个对象现在就是垃圾,如果定位了垃圾,则有可能会被垃圾回收器回收。
如果要定位什么是垃圾,有两种方式来确定,第一个是引用计数法,第二个是可达性分析算法
引用计数法
一个对象被引用了一次,在当前的对象头上递增一次引用次数,如果这个对象的引用次数为0,代表这个对象可回收
此时demo变量指向这个对象,所以ref=1;
如果把demo设置成null,则没有变量指向这个对象,所以ref=0,如果ref=0,代表这个对象可以回收
当出现循环引用的话,则引用计数法就会失效
如果再让a=null,b=null,则会产生两个对象的ref都是1,无法被垃圾回收,所以会造成内存泄露
可达性分析方法
现在的虚拟机采用的都是通过可达性分析算法来确定哪些内容是垃圾。
首先会有一个GC Roots,如果可以跟GC Roots关联,说明不能被垃圾回收,如果不能找到,如下图的X,Y,就会被垃圾回收
X,Y这两个节点是可回收的
- Java 虚拟机中的垃圾回收器采用可达性分析来探索所有存活的对象
- 扫描堆中的对象,看是否能够沿着 GC Root 对象 为起点的引用链找到该对象,找不到,表示可以回收
哪些对象可以作为GC Roots
虚拟机栈(栈帧中的本地变量表)中引用的对象
方法区中类静态属性引用的对象
方法区中常量引用的对象
本地方法栈中 JNI(即一般说的 Native 方法)引用的对象