点击蓝色“程序员的时光 ”关注我 ,标注“星标”,及时阅读最新技术文章!
小伙伴儿们,你们好!上一次咱们了解了JVM基础知识——全面解析JVM,超详细!
今天来学习JVM垃圾回收相关内容,做为面试必问的知识点,来深刻了解一波!
1,判断对象是否死亡

1.1,引用计数算法
public class ReferenceCountingGc {
public Object instance = null;
public static final int _1MB = 1024*1024;
public static void main(String[] args) {
ReferenceCountingGc objA = new ReferenceCountingGc();
ReferenceCountingGc objB = new ReferenceCountingGc();
objA.instance = objB;
objB.instance = objA;
objA = null;
objB = null;
}
}
1.2,可达性分析算法

-
虚拟机栈(栈帧中的本地变量表)中引用的对象 -
方法区中类静态属性引用的对象 -
方法区中常量引用的对象 -
本地方法栈(Native 方法)中引用的对象
2,再谈引用
reference
类型的数据存储的数值表明的是另外一块内存的起始地址,就称这块内存表明一个引用。JDK1.2 之后,Java 对引用的概念进行了扩充,将引用分为强引用、软引用、弱引用、虚引用四种(引用强度逐渐减弱)。
2.1,强引用
OutOfMemoryError
错误,使程序异常终止,也不会靠随意回收具备强引用的对象来解决内存不足问题。
2.2,软引用
ReferenceQueue
)联合使用,若是软引用所引用的对象被垃圾回收,JAVA 虚拟机就会把这个软引用加入到与之关联的引用队列中。
2.3,弱引用
ReferenceQueue
)联合使用,若是弱引用所引用的对象被垃圾回收,Java 虚拟机就会把这个弱引用加入到与之关联的引用队列中。
2.4,虚引用
OutOfMemory
)等问题的产生。
3,废弃常量以及无用类
3.1,如何判断一个常量是废弃常量?
abc
" ,若是当前没有任何
String
对象引用该字符串常量的话,就说明常量"
abc
"就是废弃常量,若是这时发生内存回收的话并且有必要的话,"
abc
"就会被系统清理出常量池。
3.2,如何判断一个类是无用的类?
-
该类全部的实例都已经被回收,也就是 Java 堆中不存在该类的任何实例。 -
加载该类的 ClassLoader
已经被回收。 -
该类对应的 java.lang.Class
对象没有在任何地方被引用,没法在任何地方经过反射访问该类的方法。
4,垃圾收集算法
4.1,标记--清除算法
-
效率问题:标记和清除两个过程的效率都不高; -
空间问题:标记清除以后会产生大量不连续的内存碎片,空间碎片太多可能会致使之后在程序运行过程当中须要分配较大对象时,没法找到足够的连续内存而不得不提早触发另外一次垃圾收集动做。

4.2,复制算法

4.3,标记--整理算法

4.4,分代收集算法
5,垃圾收集器

5.1,Serial
收集器
Serial
收集器是最基本、历史最悠久的垃圾收集器了。从名字上看是串行的意思,这个收集器是一个单线程的新生代收集器。它的 “单线程” 的意义不只仅意味着它只会使用一条垃圾收集线程去完成垃圾收集工做,更重要的是它在进行垃圾收集工做的时候必须暂停其余全部的工做线程( "Stop The World" ),直到它收集结束。

5.2,ParNew
收集器

-
并行(Parallel) :指多条垃圾收集线程并行工做,但此时用户线程仍然处于等待状态。 -
并发(Concurrent):指用户线程与垃圾收集线程同时执行(但不必定是并行,可能会交替执行),用户程序在继续运行,而垃圾收集器运行在另外一个 CPU 上。
5.3,Parallel Scavenge
收集器

java -XX:+PrintCommandLineFlags -version
命令查看
-XX:InitialHeapSize=197918400 -XX:MaxHeapSize=3166694400 -XX:+PrintCommandLineFlags -XX:+UseCompressedClassPointers -XX:+UseCompressedOops -XX:-UseLargePagesIndividualAllocation -XX:+UseParallelGC
java version "1.8.0_144"
Java(TM) SE Runtime Environment (build 1.8.0_144-b01)
Java HotSpot(TM) 64-Bit Server VM (build 25.144-b01, mixed mode)

Parallel Scavenge + Parallel Old
,若是指定了
-XX:+UseParallelGC
参数,则默认指定了
-XX:+UseParallelOld GC
,可使用
-XX:-UseParallelOldGC
来禁用该功能。
5.4,Serial Old
收集器
5.5,Parallel Old
收集器
5.6,CMS
收集器
-
初始标记: 暂停全部的其余线程,并记录下直接与 root 相连的对象,速度很快 ; -
并发标记: 同时开启 GC 和用户线程,用一个闭包结构去记录可达对象。但在这个阶段结束,这个闭包结构并不能保证包含当前全部的可达对象。由于用户线程可能会不断的更新引用域,因此 GC 线程没法保证可达性分析的实时性。因此这个算法里会跟踪记录这些发生引用更新的地方。 -
从新标记: 从新标记阶段就是为了修正并发标记期间由于用户程序继续运行而致使标记产生变更的那一部分对象的标记记录,这个阶段的停顿时间通常会比初始标记阶段的时间稍长,远远比并发标记阶段时间短 -
并发清除: 开启用户线程,同时 GC 线程开始对未标记的区域作清扫。

-
对 CPU 资源敏感; -
没法处理浮动垃圾; -
它使用的回收算法-“标记-清除”算法会致使收集结束时会有大量空间碎片产生。
5.7,G1
收集器
-
并行与并发:G1 能充分利用 CPU、多核环境下的硬件优点,使用多个 CPU(CPU 或者 CPU 核心)来缩短 Stop-The-World 停顿时间。部分其余收集器本来须要停顿 Java 线程执行的 GC 动做,G1 收集器仍然能够经过并发的方式让 java 程序继续执行。 -
分代收集:虽然 G1 能够不须要其余收集器配合就能独立管理整个 GC 堆,可是仍是保留了分代的概念。 -
空间整合:与 CMS 的“标记--清理”算法不一样,G1 从总体来看是基于“标记整理”算法实现的收集器;从局部上来看是基于“复制”算法实现的。 -
可预测的停顿:这是 G1 相对于 CMS 的另外一个大优点,下降停顿时间是 G1 和 CMS 共同的关注点,但 G1 除了追求低停顿外,还能创建可预测的停顿时间模型,能让使用者明确指定在一个长度为 M 毫秒的时间片断内。

《深刻理解Java虚拟机(第2版).周志明》
https://xiaozhuanlan.com/topic/1847690325#section1java
本文分享自微信公众号 - 程序员的时光(gh_9211ec727426)。
若有侵权,请联系 support@oschina.cn 删除。
本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一块儿分享。java