一. GC根底原理
1. 怎么找到须要回收的垃圾?
咱们都晓得有两种算法:即 援用计数算法 和 可达性剖析算法。
- 援用计数法:
在对象中增加一个援用计数器,每当一个中央援用它时,计数器就加一;当援用生效时,计数器值就减一;任何时刻计数器为零的对象就是不可能再被应用的。
存在的问题:不能解决循环援用
- 可达性剖析算法:
就是通过一系列的“GC Roots”,也就是根对象作为起始节点汇合,从根节点开始,依据援用关系向下搜寻,搜寻过程所走过的门路称为援用链,如果某个对象到GC Roots间没有任何援用链相连。用图论的话来说就是从GC Roots到这个对象不可达时,则证实此对象是不可能再被应用的。所以此对象就是能够被回收的对象。
- GC Root次要包含以下几类元素:
- 虚拟机栈中援用的对象
- Class 外面的static变量
- JNI本地办法
- 办法区中常量援用的对象(比方:字符串常量池(string Table) 里的援用)
- 所有被同步锁synchronized持有的对象
- Java虚拟机外部的援用
根本数据类型对应的Class对象,一些常驻的异样对象(如:NullPointerException、OutOfMemoryError) ,零碎类加载器
2. 怎么革除垃圾?
3. GC分代收集
随着工夫的推移,经验垃圾回收后存活下的数据大小状况。能够看出大部分对象存活期很短,随着工夫的推移越来越少的对象存活下来。因而,能够针对不同的堆内存采取不同的回收频率和办法,以进步JVM性能。
- 新生代(Young Generation)
新生代又叫年老代,大多数对象在新生代中被创立,很多对象的生命周期很短。每次新生代的垃圾回收(又称Young GC、Minor GC、YGC)后只有大量对象存活,所以应用复制算法,只需大量的复制操作老本就能够实现回收
新生代内又分三个区:一个Eden区,两个Survivor区(S0、S1,又称From Survivor、To Survivor),大部分对象在Eden区中生成。当Eden区满时,还存活的对象将被复制到两个Survivor区(中的一个)。当这个Survivor区满时,此区的存活且不满足降职到老年代条件的对象将被复制到另外一个Survivor区。对象每经验一次复制,年龄加1,达到降职年龄阈值后,转移到老年代
- 老年代(Old Generation)
在新生代中经验了N次垃圾回收后依然存活的对象,就会被放到老年代,该区域中对象存活率高。老年代的垃圾回收通常应用“标记-整顿”算法
4. 内存调配策略
Java提供的主动内存治理,能够归结为解决了对象的内存调配和回收的问题,后面曾经介绍了内存回收,上面介绍几条最广泛的内存调配策略
- 对象优先在Eden区调配 大多数状况下,对象在先新生代Eden区中调配。当Eden区没有足够空间进行调配时,虚拟机将发动一次Young GC
- 大对象间接进入老年代 JVM提供了一个对象大小阈值参数(-XX:PretenureSizeThreshold,默认值为0,代表不论多大都是先在Eden中分配内存),大于参数设置的阈值值的对象间接在老年代调配,这样能够防止对象在Eden及两个Survivor间接产生大内存复制
- 长期存活的对象将进入老年代 对象每经验一次垃圾回收,且没被回收掉,它的年龄就减少1,大于年龄阈值参数(-XX:MaxTenuringThreshold,默认15)的对象,将降职到老年代中
- 空间调配担保 当进行Young GC之前,JVM须要预估:老年代是否可能包容Young GC后新生代降职到老年代的存活对象,以确定是否须要提前触发GC回收老年代空间,基于空间调配担保策略来计算:
Young GC之后如果胜利(Young GC后降职对象能放入老年代),则代表担保胜利,不必再进行Full GC,进步性能;如果失败,则会呈现“promotion failed”谬误,代表担保失败,须要进行Full GC
- 动静年龄断定 新生代对象的年龄可能没达到阈值(MaxTenuringThreshold参数指定)就降职老年代,如果Young GC之后,新生代存活对象达到雷同年龄所有对象大小的总和大于任一Survivor空间(S0 或 S1总空间)的一半,此时S0或者S1区行将包容不了存活的新生代对象,年龄大于或等于该年龄的对象就能够间接进入老年代,毋庸等到MaxTenuringThreshold中要求的年龄
另外,如果Young GC后S0或S1区不足以包容:未达到降职老年代条件的新生代存活对象,会导致这些存活对象间接进入老年代,须要尽量避免
二. 垃圾收集器的进化史
1. 古典时代的垃圾回收算法:
-
Serial
- 年老代 Serial
- 老年代 Serial Old
-
Parallel
- 年老代 Parallel Scavenge
- 老年代 Parallel Old
2. 中古时代的垃圾回收算法:
-
CMS: Concurrent Mark Sweep
- 低延时的零碎
- 不进行Compact
- 用于老年代
- 配合Serial/ParNew应用
3. 古代垃圾回收算法:
- G1:Garbage first
4. 将来时代的垃圾回收算法:
- ZGC
- Shonandoah
发表回复