Java虚拟机-读书笔记4-垃圾回收(1)

时间:2022-12-27 15:28:18

    在java运行时内存区域中,程序计数器,虚拟机栈,本地方法栈3个区域随线程而生,随线程而灭.栈中的栈帧随着方法的进入和退出有条不紊地执行者出栈和入栈操作.每一个栈帧分配多少内存基本上在类结构确定下来时就已知了(尽管在运行时期会由JIT编译器进行一些优化).因此这些区域的内存分配和回收都具备确定性了.因为方法结束或线程结束,内存也自然都回收了.

   而方法区则不一样,一个接口的多个实现类需要的内存可能不一样,一个方法的多个分支需要的内存也可能不一样,只有在运行时我们才能知道会创建那些对象.多以这些区域的内存分配和回收都是动态的.垃圾回收器所关注的是这部分区域.

一.判断对象是否活着,是否应该被回收的方法:

1.引用计数算法

    给对象添加一个引用计数器,当一个地方引用他,计数器就+1,当引用失效,计数器-1,任何时刻计数器为0的对象就是不可能再被引用的.这种方式实现简单.效率高.但无法解决循环引用的问题.(如:A引用B,B引用A,但没有其他地方引用它们,它们的计数器都不为0

),因此主流的Java虚拟机中没有使用这种算法管理内存.

2.可达性分析算法

    这种算法的思路就是通过一系列称为"GC Roots"的对象作为起始点,从这些节点开始向下搜索,搜索所走过的路径称为引用链,当一个对象到GC Roots没有任何引用链相连时,则证明此对象是不可用的.

        可作为GC Roots的对象:

    a)虚拟机栈(栈帧中的本地变量表)中引用的对象

    b)方法区中类静态属性引用的对象

    c)方法区中常量引用的对象

    d)本地方法栈中JNI引用的对象

Java虚拟机-读书笔记4-垃圾回收(1)

如上图:obj_1,obj_2,obj_3随互相关联,但是他们到GC Roots是不可达的,所以他们会被判定为可回收对象.

二 引用类型

    强引用:类似"Object obj = new Object()",只要强引用存在,垃圾回收器就永远不会回收被引用的对象;

    软引用:用来描述一下还有用但非必须的对象,对于软引用关联的对象,在系统即将发生内存溢出之前,将会把这些对象列进回收范围之中进行第二次回收.

    弱引用:也是用来描述非必须对象的,单笔软引用更弱,被弱引用对象只能生存到下次垃圾收集发生之前;

    虚引用:唯一的目的就是在对象被回收之前收到一个系统通知.

三 回收方法区

    在方法区中进行垃圾回收,性价比很低.每次堆中都可以回收75%-95%的空间,而永久代的垃圾收集效率远低于此,

    方法区的回收主要两部分内容:废弃常量和无用的类;

    废弃常量就是在任何地方都没有被引用的常量,发生内存回收时,这种常量就会被清理出常量池.常量池中的其他类,方法,字段的符号引用也与此类型.

    无用的类的判断条件:

    1.该类的所有实例都已经被回收,

    2.加载该类的ClassLoader已经被回收,

    3.该类对应的class对象没有在任何地方被引用,无法再任何对象通过反射访问该类的方法.

无用的类是否被回收还由-Xnlclassgc参数进行控制.