1.垃圾回收机制:
首先呢,我在研究垃圾回收机制的原理时,要知道需要回收的是什么呢?
1.1什么是垃圾(主要回收那些东西):
程序计数器、虚拟机栈、本地方法栈 3 个区域随线程生灭(因为是线程私有),栈中的栈帧随着方法的进入和退出而有条不紊地执行着出栈和入栈操作。而 Java 堆和方法区则不一样,一个接口中的多个实现类需要的内存可能不一样,一个方法中的多个分支需要的内存也可能不一样,我们只有在程序处于运行期才知道那些对象会创建,这部分内存的分配和回收都是动态的,垃圾回收期所关注的就是这部分内存。
方法区主要针对的是常量池的回收和对类型的卸载,堆主要针对的是不在使用的对象进行内存回收,我们常说的GC就是对堆内存的回收,堆内存可以进一步划分为新生代和老年代(比例大概是1:2),老年代会发生full GC(标志-整理) 新生代会发生 Minor GC (标志-复制),年轻代又划分为 三个部分 Eden区和survivor区(from和to),比例为8:1:1。
1.2垃圾回收的过程:
在GC开始时,对象会存在Enden区和from区,to区为空,当Eden区存满,无法分配内存给对象的时候,会触发一次Minor GC ,进行GC时,会将Eden区存活的对象放入to区,from区中存活的对象会根据年龄值决定去留,达到阀值得会被移动到年代,没有达到的会被复制到to区;这时Eden区和from区已经清空,接下来要交换from与to的角色,以保证每次开始GC时to区是空的,MinorGC 会一直重复这个过程,直到to区被填满,填满后整个移动到老年代。如果老年代空间不足,则会触发Full GC ,
GC年龄阈值默认是15,该阈值是否可以调整?能否调整为16?年龄阈值是可以调整的,但是由于对象头中只分配了 4bit 位用于记录对象的GC年龄,因此最大只能调整为15
1.3对象是否存活:
哪究竟什么样的对象,会被成为垃圾呢?
垃圾收集器在对堆进行回收前,首先要确定对象是否存活,判断对象是否存活主要有两种算法:引用计数算法 和 可达性分析算法。
1)引用计数算法:对象创建时,给对象添加一个引用计数器,每当有一个地方引用到它时,计数器值加1;引用失效时,计数器值减1;当计数值值为0时,这个对象就是不可能再被引用的。