一、GC主要针对什么区域
1. 程序计数器、虚拟机栈、本地方法栈,3个部分随线程而生死。每个栈桢分配多少内存基本上是在类结构确定下来时就已确定,大体上可认为是 编译期可知。
2. 而 堆 和 方法区 则不一定,如一个接口多个实现类需要内存不一样,一个方法多个分支需要分配内存也不一样;这些只有一实现运行中才能得知会创建那些对象,这部分内存的分配 和 回收 都是动态的。GC主要关注的也是这两个部分。
二、对象的“存活”:
1、引用计数法:在各个对象中添加一个引用计数器。
a. 实现简单,判定效率高;
b. 但主流JVM没有用这个方法来判定;主要因为它很难解决对象间的相互循环引用问题。
2、可达性分析算法:
a. 主流的程序语言使用的方法。
b. 通过GC Roots的对象作作为起点,从这些起点向下去搜索,所走过的路径叫做引用链,当一个对象到GC Roots没有任何引用链连接时,则证明此对象不可达。
c. 可作为GC Roots的对象:
1. 方法区中类静态属性、常量引用的对象;(Static修饰)
2. 虚拟机栈、本地方法栈中引用的对象;
三、最终判定对象是否被回收:
在可达性分析算法中不可达的对象,也并非就判定为“死亡”了;判定一个对象最终是否死亡,至少经历两次标记过程:
1. 不可达的对象会被 第一次标记;
2. 被第一次标记的对象进行 判断是否有必要执行finalize(),若对象覆盖了finalize()方法 且 finalize() 没有执行过,若都满足则执行finalize();
3. 在finalize()中,若对象重新和引用链上的任一对象建立关联,则不会被第二次标记,它则不会被回收。
时间: 2024-10-07 09:41:37