1.  概念理解

1.1.  并行(Parallel)与并发(Concurrent)

并行:指多个垃圾收集线程并行工作,但此时用户线程仍然处于等待状态

并发:指用户线程与垃圾收集线程同时执行

1.2.  Minor GC 与 Major GC

Minor GC:指发生在新生代的垃圾收集动作,因为Java对象大多都具备朝生夕灭的特性,所以Minor GC非常频繁,一般回收速度也比较快。

Major GC:指发生在老年代的GC,出现了Major GC,经常会伴随至少一次的Minor GC。Major GC的速度一般会比Minor GC慢10倍以上。

1.3.  吞吐量

吞吐量就是CPU用于运行用户代码的时间与CPU总消耗时间的比值,即吞吐量 = 运行用户代码时间 /(运行用户代码时间 + 垃圾收集时间)

假设虚拟机总共运行了100分钟,其中垃圾收集花掉1分钟,那吞吐量就是99%

2.  对象存活判断

回收的第一步是标记出哪些需要回收,为此需要有一种方式来判断对象是否存活,存活的不用回收

判断的方式是可达性分析,通过遍历对象的引用树来找出存活的对象

所谓的引用树本质上是有根的图结构,它沿着对象的根句柄向下查找到活着的节点,并标记下来;其余没有被标记的节点就是死掉的节点,这些对象就是可以被回收的

遍历从GC Roots开始,那么哪些对象可作为GC Roots对象?

  • 虚拟机栈中应用的对象
  • 方法区里面的静态对象
  • 方法区常量池的对象
  • 本地方法栈JNI应用的对象

3. 垃圾回收算法

3.1.  标记-清除算法(Mark-Sweep)

标记-清除算法分为两个阶段:标记阶段和清除阶段。标记阶段的任务是标记出所有需要被回收的对象,清除阶段就是回收被标记的对象所占用的空间。

从图中可以很容易看出标记-清除算法实现起来比较容易,但是有一个比较严重的问题就是容易产生内存碎片,碎片太多可能会导致后续过程中需要为大对象分配空间时无法找到足够的空间而提前触发新的一次垃圾收集动作。

优点:简单

缺点:容易产生大量碎片

3.2.  复制算法(Copying)

它将可用内存划分为两块,每次只使用其中的一块。当这一块的内存用完了,就将还存活着的对象复制到另外一块上面,然后再把已使用的内存空间一次清理掉,这样一来就不容易出现内存碎片的问题。

Java的新生代串行垃圾回收器中使用了复制算法的思想。新生代分为 eden 空间、survivor from 空间、survivor to 空间 3 个部分。其中survivor from 空间和 survivor to 空间可以视为用于复制的两块大小相同、地位相等,且可进行角色互换的空间块。默认Eden与Survivor的比例是8:1

这种算法虽然实现简单,运行高效且不容易产生内存碎片,但是却对内存空间的使用做出了高昂的代价,因为能够使用的内存缩减到原来的一半。

很显然,Copying算法的效率跟存活对象的数目多少有很大的关系,如果存活对象很多,那么Copying算法的效率将会大大降低。

优点:简单,不易产生碎片

缺点:可用内存变少,且如果存活对象较多,则复制的效率会大大降低

3.3.  标记-整理算法(Mark-Compact)

该算法标记阶段和Mark-Sweep一样,但是在完成标记之后,它不是直接清理可回收对象,而是将存活对象都向一端移动,然后清理掉端边界以外的内存。

复制算法的高效性是建立在存活对象少、垃圾对象多的前提下的。这种情况在年轻代经常发生,但是在老年代更常见的情况是大部分对象都是存活对象。如果依然使用复制算法,由于存活的对象较多,复制的成本也将很高。

标记-压缩算法修复了标记-清除算法的短板——它将所有标记的也就是存活的对象都移动到内存区域的开始位置。这种方法的缺点就是GC暂停的时间会增 长,因为你需要将所有的对象都拷贝到一个新的地方,还得更新它们的引用地址。相对于标记-清除算法,它的优点是不容易产生碎片;相对于复制算法,它的优点是可用内存空间不会减少。

优点:不易产生碎片,充分利用可用内存空间

缺点:用户等待时间变长

3.4.  分代回收算法(Generational Collection)

分代回收算法是目前大部分JVM的垃圾收集器采用的算法。它的核心思想是根据对象存活周期的不同将内存划分为几块。根据每块内存区间的特点,使用不同的回收算法,以提高垃圾回收的效率。

以HotSpot虚拟机为例,它将所有的新建对象都放入称为年轻代的内存区域,年轻代的特点是对象会很快回收,因此,在年轻代就选择效率较高的复制算法。当一个对象经过几 次回收后依然存活,对象就会被放入称为老生代的内存空间。在老生代中,几乎所有的对象都是经过几次垃圾回收后依然得以幸存的。因此,可以认为这些对象在一 段时期内,甚至在应用程序的整个生命周期中,将是常驻内存的。如果依然使用复制算法回收老生代,将需要复制大量对象。再加上老生代的回收性价比也要低于新生代,因此这种做法也是不可取的。根据分代的思想,可以对老年代的回收使用与新生代不同的标记-压缩算法,以提高垃圾回收效率。

目前大部分垃圾收集器对于新生代都采取Copying算法,因为新生代中每次垃圾回收都要回收大部分对象,也就是说需要复制的操作次数较少,但是实际中并不是按照1:1的比例来划分新生代的空间的,一般来说是将新生代划分为一块较大的Eden空间和两块较小的Survivor空间(一般为8:1:1),每次使用Eden空间和其中的一块Survivor空间,当进行回收时,将Eden和Survivor中还存活的对象复制到另一块Survivor空间中,然后清理掉Eden和刚才使用过的Survivor空间。

而由于老年代的特点是每次回收都只回收少量对象,一般使用的是Mark-Compact算法。

(PS:年轻代一般使用复制算法,年老代一般使用标记整理算法)

4.  垃圾收集器

新生代收集器:Serial、ParNew、Parallel Scavenge

老年代收集器:Serial Old、Parallel Old、CMS

4.1.  Serial 收集器

串行GC,采用复制算法

4.2.  ParNew 收集器

并行GC,采用复制算法,相当于Serial的多线程版本

4.3.  Parallel Scavenge 收集器

并行GC,采用复制算法。追求高吞吐量,高效利用CPU。吞吐量一般为99%, 吞吐量= 用户线程时间 / (用户线程时间+GC线程时间)

这里注意,经过测试JDK 1.8.0_152默认垃圾收集器为:PS MarkSweep 和 PS Scavenge,而并不是G1

4.4.  Serial Old 收集器

串行GC,采用标记整理算法,Serial老年代版本

4.5.  Parallel Old 收集器

并行GC,采用标记整理算法,它是Parallel Scavenge收集器的老年代版本

4.6.  CMS 收集器

并行GC,并发,采用标记清除算法

CMS(Concurrent Mark Sweep) 收集器是一种以获取最短回收停顿时间为目标的收集器。

CMS整个过程分为4个步骤:

  1. 初始标记(CMS initial mark) -stop the world
  2. 并发标记(CMS concurrent mark)
  3. 重新标记(CMS remark) -stop the world
  4. 并发清除(CMS concurrent sweep)

4.7.  G1 收集器

最先进的收集器,独立完成分代回收

5.  查看垃圾回收器

5.1.  命令行

java -XX:+PrintCommandLineFlags -version

也就是说,本例中JVM使用的垃圾回收器是 Parallel Scavenge (新生代,并行GC) + Serial Old (老年代,串行GC)

5.2.  代码

6.  其它相关

Java8虚拟机内存模型

JVM垃圾回收的更多相关文章

  1. JVM垃圾回收机制总结:调优方法

    转载: JVM垃圾回收机制总结:调优方法 JVM 优化经验总结 JVM 垃圾回收器工作原理及使用实例介绍

  2. JVM内存管理和JVM垃圾回收机制

    JVM内存管理和JVM垃圾回收机制(1) 这里向大家描述一下JVM学习笔记之JVM内存管理和JVM垃圾回收的概念,JVM内存结构由堆.栈.本地方法栈.方法区等部分组成,另外JVM分别对新生代和旧生代采 ...

  3. JDK分析工具&JVM垃圾回收(转)

    转自:http://blog.163.com/itjin45@126/blog/static/10510751320144201519454/ 官方手册:http://docs.oracle.com/ ...

  4. 老李分享:jvm垃圾回收

    老李分享:jvm垃圾回收   poptest是国内唯一一家培养测试开发工程师的培训机构,以学员能胜任自动化测试,性能测试,测试工具开发等工作为目标.如果对课程感兴趣,请大家咨询qq:908821478 ...

  5. jvm - 垃圾回收

    jvm - 垃圾回收 注意 : 本系列文章为学习系列,部分内容会取自相关书籍或者网络资源,在文章中间和末尾处会有标注 垃圾回收的意义 它使得java程序员不再时时刻刻的关注内存管理方面的工作. 垃圾回 ...

  6. JVM垃圾回收机制概述

    JVM垃圾回收机制概述 1.定义 是指JVM用于释放那些不再使用的对象所占用的内存. 2.方式 2.1引用计数(早期) 当引用程序创建引用以及引用超出范围时,JVM必须适当增减引用数.当某个对象的引用 ...

  7. Java虚拟机学习笔记——JVM垃圾回收机制

    Java虚拟机学习笔记——JVM垃圾回收机制 Java垃圾回收基于虚拟机的自动内存管理机制,我们不需要为每一个对象进行释放内存,不容易发生内存泄漏和内存溢出问题. 但是自动内存管理机制不是万能药,我们 ...

  8. JVM基础系列第8讲:JVM 垃圾回收机制

    在第 6 讲中我们说到 Java 虚拟机的内存结构,提到了这部分的规范其实是由<Java 虚拟机规范>指定的,每个 Java 虚拟机可能都有不同的实现.其实涉及到 Java 虚拟机的内存, ...

  9. Java虚拟机垃圾回收:内存分配与回收策略 方法区垃圾回收 以及 JVM垃圾回收的调优方法

    在<Java对象在Java虚拟机中的创建过程>了解到对象创建的内存分配,在<Java内存区域 JVM运行时数据区>中了解到各数据区有些什么特点.以及相关参数的调整,在<J ...

  10. JVM垃圾回收算法解析

    JVM垃圾回收算法解析 标记-清除算法 该算法为最基础的算法.它分为标记和清除两个阶段,首先标记出需要回收的对象,在标记结束后,统一回收.该算法存在两个问题:一是效率问题,标记和清除过程效率都不太高, ...

随机推荐

  1. 使用Kazoo操作ZooKeeper服务治理

    单机服务的可靠性及可扩展性有限,某台服务宕机可能会影响整个系统的正常使用:分布式服务能够有效地解决这一问题,但同时分布式服务也会带来一些新的问题,如:服务发现(新增或者删除了服务如何确保能让客户端知道 ...

  2. 恢复数据库的redo日志文件(由于异常关机引起)

    需要事先进入sqlplus select * from v$log 打印相关文件信息 1.recover database until cancel(recover database using ba ...

  3. 指针*p,p,&p等辨别

    #include<iostream> #include<iomanip> #include<cmath> using namespace std; int main ...

  4. fiddler 抓取 htts 失败

    1.清除C:\Users\Administrator\AppData\Roaming\Microsoft\Crypto\RSA 目录下所有文件(首次安装fiddler请忽略) 2.清除电脑上的根证书, ...

  5. 一道令人抓狂的零一背包变式 -- UVA 12563 Jin Ge Jin Qu hao

    题目链接: https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_proble ...

  6. Markdown初使用

    Markdown是一种纯文本格式的标记语言.通过简单的标记语法,它可以使普通文本内容具有一定的格式. 相比WYSIWYG编辑器 优点:1.因为是纯文本,所以只要支持Markdown的地方都能获得一样的 ...

  7. 数据分析——matplotlib

    基础 # coding=utf-8 import matplotlib.pyplot as pt import numpy as np from matplotlib import font_mana ...

  8. 继承ipkPlayer中出现的一些错误汇总

    1.下载完ffmpeg后,我们再在终端执行下面两个命令: cd ios./compile-ffmpeg.sh clean./compile-ffmpeg.sh all 大体流程如下  这里如果出现 x ...

  9. Bypass_Disable_functions_Shell

    Bypass_Disable_functions_Shell https://github.com/l3m0n/Bypass_Disable_functions_Shell 一个各种方式突破Disab ...

  10. Multi-Get API

    multiGet API并行地在单个http请求中执行多个get请求. Multi-Get Request MultiGetRequest构造函数为空,需要你添加`MultiGetRequest.It ...