小伙子,你真的清楚 JVM GC ?
序











正文
如何确定垃圾?
前面已经提到 JVM 可以采用 引用计数法 与 可达性分析算法 来确定需要回收的垃圾,我们来具体看一下这两种算法:
- 引用计数法
该方法实现为:给每个对象添加一个引用计数器,每当有一个地方引用它时,引用计数值就+1,当引用失效时,引用计数值就-1,任何时刻引用计数值为0的对象就可以被回收,当一个对象被垃圾收集器收集时,被它引用的对象引用计数值就-1,所以在这种方法中一个对象被垃圾收集会导致后续其他对象的垃圾收集行动。
优点:简单、高效;
缺点:当两个对象相互引用的时候就无法回收,导致内存泄漏。
- 可达性分析法
为了解决对象间相互引用问题,Java 采用了可达性分析法,基本实现思路为:通过一系列 "GC Roots" 对象作为起点,从这些节点开始向下搜索,搜索所走过的路径称为引用链,当一个对象到 "GC Roots" 没有任何引用链相连时,则称该对象是不可达的,此时,该对象还处于缓刑阶段,要真正宣判一个对象为可回收对象,至少要经历两次标记过程。
哪些对象可以作为 "GC Roots" ?
1、通过System Class Loader或者Boot Class Loader加载的class对象
2、处于激活状态的线程
3、栈中的对象
4、JNI栈中的对象
5、JNI中的全局对象
6、正在被用于同步的各种锁对象
7、JVM自身持有的对象,比如系统类加载器等
垃圾回收算法
通过上面面试者的回答,我们已经知道垃圾收集算法主要包括:复制算法、标记清除算法、标记整理算法、分代回收算法,我们来具体看一下:
- 复制算法
该方法实现为:将内存分为大小相等的两块,每次只使用其中一块,当这一块内存满了后将存活的对象复制到另一块上去,把已使用的内存清掉。如图所示:

优点:简单、高效、不会产生内存碎片;
缺点:可用内存减少为原来的一半,造成内存浪费。
- 标记清除算法
该方法实现分为两个阶段,标注和清除,标记阶段找到所有可访问的对象,做个标记 ;清除阶段遍历堆,把未被标记的对象回收。如图所示:

缺点:碎片化严重。
- 标记整理算法
该方法不直接对可回收对象进行清理,而是让所有可用的对象都向一端移动,然后直接清理掉边界外的对象,解决了标记清除算法带来的碎片化问题。如图所示:

- 分代回收算法
分代回收算法是目前大部分 JVM 所采用的方法,其核心思想是根据对象存活的生命周期不同,将内存划分为不同的区域,一般情况下将 GC 堆划分为新生代和老年代;老年代的特点是:对象生命周期较长,每次垃圾回收时只有少量对象需要被回收;新生代的特点是:对象大部分朝生夕死,生命周期短,每次垃圾回收时都有大量对象需要被回收;因此,可以根据不同区域选择不同的算法,使垃圾回收更加合理、高效,如:新生代采用效率较高的复制算法,老年代采用不会产生内存碎片,也不会发生内存浪费的标记整理算法。
垃圾收集器
常用的垃圾收集器都有哪些呢?我们来具体看一下:
- Serial 垃圾收集器
Serial 曾经是 JDK1.3.1 之前新生代唯一的垃圾收集器;Serial 是一个单线程的收集器,在进行垃圾收集的同时,必须暂停其他所有的工作线程,直到垃圾收集结束;但同时 Serial 也是简单高效的,对于限定单个 CPU 环境来说,没有线程交互的开销,可以获得最高的单线程垃圾收集效率。
- ParNew 垃圾收集器
ParNew 是 Serial 多线程版,也使用复制算法,除了使用多线程进行垃圾收集之外,其余的行为和 Serial 收集器完全一样。
- Parallel Scavenge 收集器
Parallel Scavenge 是一个新生代垃圾收集器,同样使用复制算法,也是一个多线程的垃圾收集器,它重点关注的是程序达到一个可控制的吞吐量(吞吐量=运行用户代码时间/(运行用户代码时间+垃圾收集时间)),高吞吐量可以最高效率地利用 CPU 时间,尽快地完成程序的运算任务,主要适用于在后台运算而不需要太多交互的任务。
- Serial Old 收集器
Serial Old 是 Serial 垃圾收集器老年代版本,它是个单线程的,使用标记整理算法的收集器。
- Parallel Old 收集器
Parallel Old 收集器是 Parallel Scavenge 的老年代版本,它是多线程的,使用标记整理算法,在 JDK1.6 开始提供使用。
- CMS 收集器
CMS 是一种老年代垃圾收集器,其主要目标是获取最短垃圾回收停顿时间,和其它老年代使用标记整理算法不同,它使用多线程的标记清除算法;其运作过程比较复杂,整个过程分为6个步骤,包括:初始标记(CMS initial mark)、并发标记(CMS concurrent mark)、并发预清理(CMS-concurrent-preclean)、重新标记(CMS remark)、并发清除(CMS concurrent sweep)、并发重置(CMS-concurrent-reset),其中初始标记、重新标记这两个步骤仍然需要暂停其它工作线程,初始标记仅仅只是标记一下 "GC Roots" 能直接关联到的对象,速度很快,并发标记阶段就是进行 "GC Roots" 追踪的过程,而重新标记阶段则是为了修正并发标记期间,因用户程序继续运作而导致标记产生变动的那一部分对象的标记记录,这个阶段的停顿时间一般会比初始标记阶段稍长一些,但远比并发标记的时间短。
- G1 收集器
G1 是 JVM 垃圾收集器理论进一步发展的产物,相比与 CMS 收集器,G1 基于标记整理算法,不会产生内存碎片;其次,还可以非常精确控制停顿时间,在不牺牲吞吐量前提下,实现低停顿垃圾回收;G1 收集器避免全区域垃圾收集,它把堆内存划分为大小固定的几个独立区域,并且跟踪这些区域的垃圾收集进度,同时在后台维护一个优先级列表,每次根据所允许的收集时间,优先回收垃圾最多的区域;区域划分和优先级区域回收机制,确保 G1 收集器可以在有限时间获得最高的垃圾收集效率。
小伙子,你真的清楚 JVM GC ?的更多相关文章
- 一夜搞懂 | JVM GC&内存分配
前言 本文已经收录到我的Github个人博客,欢迎大佬们光临寒舍: 我的GIthub博客 学习导图 一.为什么要学习GC&内存分配? 时代发展到现在,如今的内存动态分配与内存回收技术已经相当成 ...
- 如何避免后台IO高负载造成的长时间JVM GC停顿(转)
译者著:其实本文的中心意思非常简单,没有耐心的读者建议直接拉到最后看结论部分,有兴趣的读者可以详细阅读一下. 原文发表于Linkedin Engineering,作者 Zhenyun Zhuang是L ...
- 【转载】Java性能优化之JVM GC(垃圾回收机制)
文章来源:https://zhuanlan.zhihu.com/p/25539690 Java的性能优化,整理出一篇文章,供以后温故知新. JVM GC(垃圾回收机制) 在学习Java GC 之前,我 ...
- JVM GC机制
垃圾收集主要是针对堆和方法区进行. 回收机制: 现在的JVM基本都使用分代回收机制,把堆中内存区域分为新生代,老年代. 新生代: Eden(80%) Survivor0(10%) Survivor1( ...
- 深入浅出 JVM GC(3)
# 前言 在 深入浅出 JVM GC(2) 中,我们介绍了一些 GC 算法,GC 名词,同时也留下了一个问题,就是每个 GC 收集器的具体作用.有哪些 GC 收集器呢? Serial 串行收集器(只适 ...
- 深入浅出 JVM GC(2)
# 前言 在 深入浅出 JVM GC(1) 中,限于上篇文章的篇幅,我们留下了一个问题 : 如何回收? 这篇文章将重点讲述这个问题. 在上篇文章中,我们也列出了一些大纲,今天我们就按照那个大纲来逐个讲 ...
- JVM 自带性能监测调优工具 (jstack、jstat)及 JVM GC 调优
1. jstack:占用最多资源(CPU 内存)的Java代码 https://www.cnblogs.com/chengJAVA/p/5821218.html https://blog.csdn.n ...
- 理解JVM GC
理解JVM GC对于我们把控Java应用有很大的帮助.下面我从运维角度,把网上的JVM相关的资料整理如下,以加深对JVM GC的理解.如有错误的地方,请看官指正. JVM内存使用分类 JVM的内存分区 ...
- Java性能优化之JVM GC(垃圾回收机制)
Java的性能优化,整理出一篇文章,供以后温故知新. JVM GC(垃圾回收机制) 在学习Java GC 之前,我们需要记住一个单词:stop-the-world .它会在任何一种GC算法中发生.st ...
随机推荐
- PATA 1027 Colors In Mars
#include <cstdio> char radix[13] = {'0','1','2','3','4','5','6','7','8','9','A','B','C'}; int ...
- php设计模式-责任链模式
责任链模式更像是一种简化多种场景下调用处理的一种设计模式,特别适合if-else分支判断很多的场景.比如是根据不同会员等级给予不同的优惠力度. 它的定义:对象的调用是由下家的应用连接起来的处理链.一直 ...
- 记一次linux通过jstack定位CPU使用过高问题或排查线上死锁问题
一.java定位进程 在服务器中终端输入命令:top 可以看到进程ID,为5421的cpu这列100多了. 记下这个数字:5421 二.定位问题进程对应的线程 然后在服务器中终端输入命令:top -H ...
- ZooKeeper入门(一)
1 基本概念 1.1 什么是ZooKeeper zookeeper是为分布式应用所设计的高可用.高性能且一致的开源协调服务 1.2 Zookeeper的特点 顺序一致性 原子性 单一视图 可靠性 实时 ...
- CSU 1808:地铁(Dijkstra)
http://acm.csu.edu.cn/csuoj/problemset/problem?pid=1808 题意:…… 思路:和之前的天梯赛的一题一样,但是简单点. 没办法直接用点去算.把边看成点 ...
- BZOJ 2039:[2009国家集训队]employ人员雇佣(最小割)
http://www.lydsy.com/JudgeOnline/problem.php?id=2039 题意:中文题意. 思路:一开始想着和之前做的最大权闭合图有点像,但是如果把边全部当成点的话,那 ...
- S7-1200 的运动控制
S7-1200 CPU本体集成点硬件输出点最高频率为100kHz,信号板上硬件集成点输出的最高频率为20kHz,CPU在使用PTO功能时将把集成点Qa.o,Qa.2或信号板的Q4.0作为脉冲输出点,Q ...
- SFC20 功能例子 注解
谁能够把这注解一下,给大家分享一下,谢谢了 LAR1 P##SOURCE L B#16#10 T LB [AR1,P#0.0] L B#1 ...
- 关于String重写的hashcode的代码分析
public int hashCode() { int h = hash; if (h == 0 && value.length > 0) { char val[] = valu ...
- 走近Java之HashMap In JDK8
HashMap,继承AbstractMap类,实现了Map接口,特性是无序不可重复,其本身的数据结构是数组加链表和红黑树.今天我们就一起来详细了解一下. 首先,需要知道,HashMap中几个关键词的含 ...