java 垃圾回收器
java14为止,所有的垃圾回收器如下图。
垃圾回收器的发展路线是沿着内存越来越大的过程而演进的。
从分代算法衍化到不分代算法。
工作在年轻代的有:Serial,Parallel,ParNew
工作在老年代的有:Serial Old,Parallel Old,CMS
G1 概念分代物理不分代
ZGC 不分代
Shenandoah 不分代
Epsilon
Serial:专指年轻代的单线程垃圾回收器,会Stop The World,采用复制垃圾回收算法。
Serial Old:是工作在老年代的单线程的垃圾回收器,采用标记清除或标记置换垃圾回收算法,会Stop The World。
CMS 里程杯式的垃圾回收器,工作线程可以跟垃圾回收线程一起工作。由此触发来jdk厂家不断的对垃圾回收器的更新换代。目前已经更新到适合WIN使用的ZGC(JDK14开始)
CMS的大体过程如下图:
内存分配过程:
内存分配过程大致如下:
1、能在栈内分配就优先在栈内分配,栈内分配无需垃圾回收,直接pop弹出栈即可;
2、无法在栈内分配的,判断其大小,巨型对象直接在老年代分配;
3、非巨型对象会现在TLAB预占一块区域,无论预占是否失败则都会在Eden区分配内存;
TLAB即Thread Local Allocation Buffer:属于Eden区的一部分,Eden区为每个线程内存预分配的区域,防止线程在Eden的地址抢用造成的效率慢。
4、Eden区的内存会在GC的时候通过复制清除算法清除垃圾,存活对象复制到S1或者S2这两个相对的分区;
5、S1和S2这个两个相对的区域存活的对象可以来回复制,复制的次数记为age,当age达到一定阈值后会晋升到老年代;
这个阈值的大小是多少呢,不同的垃圾回收器有各自的值:
Serial,Parallel,ParNew 为15;
CMS 为6;
G1为15
ZGC即后面的则没有ZGC及以后的回收器则不分代。
6、老年代的垃圾回收通常称为Mager GC也叫Full GC,因为老年代回收时会同时对年轻代进行回收。
老年代的垃圾回收算法标记清除,标记清除压缩两种算法。
7、年轻的的垃圾回收通常称为minar GC,采用复制清除垃圾回收算法。
垃圾回收算法
1、常见垃圾回收算法如下:
2、标记清除算法
标记清除算法缺点是会产生内存碎片化,造成内存使用率降低。
3、复制算法
复制算法会将存活的对象复制到一个空闲的区域,原来的区域全部作为垃圾对象整体清除。这样既能迅速清除垃圾,又不会产生内存碎片化,一般用于年轻代的垃圾回收。G1垃圾回收器每一个内存分区的垃圾回收都是采用复制算法。复制算法有个缺点,就是要复制到的空闲区域会造成一定的内存浪费。
4、标记清除压缩算法
标记清除压缩算法是先标记垃圾对象,然后清除垃圾对象,最后再把不连续的内存碎片压缩成连续的内存空间,提高内存使用效率。其缺点当然是执行效率偏低。
这边文章主要是对垃圾回收器的发展衍变做一个大致的介绍,要想清楚的理解各种收集器还需要做大量的学习研究工作。