新的一年撸起袖子继续干!


什么是垃圾:

垃圾就是不在使用的,放着站空间的对象,如放在工位的矿泉水瓶...,放到jvm中也就是在内存中已经不在使用的对象,这些无用的对象就是垃圾。

那么怎么判断这些对象是垃圾呢:

jvm提供了两种算法来识别垃圾,第一是引用计数器,第二是GCROOT可达性分析。

一:引用计数器:

描述:jvm给每个对象都增加了一个计数器,存放到对象头部,当一个对象(A)被其他对象引用后,该对象(A)的引用计数器就加一,N个对象引用的话引用计数器的数为N,当一个对象不再引用该对象(A)的时候,引用计数器就会减一,当没有对象引用,引用计数器的值也就是变为0,这个时候该对象就变成了了垃圾。

优点:

简单,效率高

缺点:

会导致循环引用问题,
/**
* 会引起循环引用问题,造成应该是垃圾的无法标记出来
*/
public class YYCountGC {  
  
    private Object instance;  
  
    public static void main(String[] args){  
        YYCountGC y1 = new YYCountGC();  
        YYCountGC y2 = new YYCountGC();  
  
        y1.instance = y2;  
        y2.instance = y1;  
  
        y1 = null;  
        y2 = null;  
    }

二:GCROOT可达性分析:

GCROOT可达性分析是对引用计数器的补充,不会存在循环引用问题。
使用如下图片来解读:


描述:

GC Root为根节点,从根节点向下找,和根节点有链接(引用)的对象成为存活对象,向下找的链成为引用链。只要对象和GCRoot对象有引用链的都是存活对象,和GCRoot没有任何链接的称为“垃圾”,也就是可回收对象,在上图中A/B都是存活对象,C/E/F/G对象都是可回收对象。
那么什么对象可以是CGRoot对象呢?

那些对象可充当GCRoot对象呢?

1.虚拟机栈中的局部变量表:线程每进入方法和出方法称为出栈和入栈,每个方法代表一个栈,栈中包含一个栈帧,栈帧中存放局部变量表中引用的对象。
2.方法区的常量 方法使用final修饰的变量引用的对象。
3.方法区的静态变量 使用static修饰的变量引用的对象
4.native修饰的方法 这个jdk中很多,如:Unsafe

少林寺三毛
5 声望0 粉丝

读读书看看报,少吃零食多睡觉