新生代垃圾收集器

1. Serial收集器

serial收集器即串行收集器,是一个单线程收集器。

串行收集器在进行垃圾回收时只使用一个CPU或一条收集线程去完成垃圾回收工作,并且会暂停其他的工作线程(stop the world),直至回收完成。适用于运行在client模式下的JVM。

在单CPU年代,串行收集器是默认的垃圾回收器,minor GC和major GC的过程都是用一个线程去处理的。

启用方式:-XX: +UseSerialGC

2. ParNew收集器

parNew收集器即并行收集器,采用的是多线程方式进行垃圾回收,可以理解为Serial收集器的多线程版本,吞吐量要比串行高很多,是服务器级别的虚拟机默认使用的,用来处理新生代的垃圾回收器。

因为采用的是并行多线程方式,建议在多CPU环境下使用,否则和Serial没有区别。

启用方式:-XX: +UseParNewGC

3. Parallel Scavenge收集器

并行的多线程垃圾收集器,采用复制算法进行垃圾回收,非常适合服务器做计算任务时使用。

一般的垃圾回收器是在尽量短的时间内进行垃圾回收,这样程序与用户交互的时间间隔比较小,不会出现长时间的卡顿现象。但是Parallel Scavenge更侧重于系统的吞吐量,高效的利用CPU,优先处理计算任务,适合交互少、运算多的场景。

通过参数-XX: MaxGcPauseMills设置GC最大停顿时间,通过参数-XX: GCTimeRatio设置吞吐量大小。

启用方式:-XX: +UseParallelGC

老年代垃圾收集器

1. Serial Old收集器

serial收集器的老年代版本,同样是单线程收集器、stop the world,使用标记整理算法。一般启用方式:UseSerialGC是Serial + Serial OldUseParNewGC是ParNew + Serial OldUseParallelGC是Parallel Scavenge + Serial Old

2. Parallel Old收集器

老年代版本的Parallel Scavenge,使用多线程 + 标记整理算法。启用方式:-XX: +UseParallelOldGC

3. CMS垃圾收集器

CMS收集器的主要目的是使垃圾回收造成的停顿时间最短,提高服务响应速度,使用标记清除算法,具有并发收集(用户线程与垃圾收集并发执行)、低停顿的特点。运行过程分为以下四个步骤:

1. 初始标记:stop the world,只是标记一下GC Roots能直接关联到的对象,速度快

2. 并发标记:进行GC RootsTracing过程

3. 重新标记:stop the world,修正并发标记期间因用户程序继续运行而导致的标记产生变动的那部分对象的标记记录。这个阶段停顿时间相对初始标记时间长,比并发标记时间短

4. 并发清除注意:

  1. CMS收集器对CPU资源敏感,这是面向并发程序设计的共性
  2. 无法处理浮动垃圾(CMS垃圾收集阶段,用户线程仍在运行,因此会有新的垃圾生成,这部分垃圾只能在下一次GC时再清理,即浮动垃圾),可能出现"Concurrent Mode Failure"失败导致另一次full GC

启用方式:-XX:+UseConcMarkSweepGC

G1收集器

G1收集器是基于标记整理算法实现的收集器,所以它不会产生内存空间碎片,并且可以精确的控制停顿时间。能让使用者明确指定在一个长度为M毫秒的时间片段内,消耗在垃圾收集上的时间不得超过N毫秒。

G1的设计原则就是简单可行的性能调优,只需声明以下参数即可:
-XX:+UseG1GC -Xmx16g -XX:MaxGCPauseMills=300

其中,-XX:+UseG1GC表明开启G1收集器,-Xmx16g设置堆内存为16g,-XX:MaxGCPauseMills=300设置GC停顿最大时间为300ms。如果我们需要调优,在内存一定的情况下,可以考虑修改该参数,当然还要根据实际业务场景来处理。

G1取消了堆内结构的新生代、老年代的物理空间划分,将整个Java堆划分为大小固定的独立区域,后台维护一个优先列表来跟踪这些区域的垃圾堆积程度,每次根据允许收集的时间,优先回收垃圾最多的区域。

G1中的Humongous区域用于存储生命周期较短的巨型对象(一个对象所占空间超过了分区容量的50%),如果一个Humongous区无法装下一个巨型对象,G1会寻找连续的H分区来存储,如果没有连续的H区满足这种情况,有时候会触发full GC。

G1收集器的运作主要划分为以下四个步骤:

  1. 初始标记:标记GC Roots能直接关联到的对象,需要停顿线程,但耗时很短
  2. 并发标记:从GC Roots开始对堆中对象进行可达性分析,找出存活的对象,这阶段耗时较长,但可与用户程序并发执行
  3. 最终标记:修正在并发标记期间因用户程序继续运作而导致标记产生变动的那一部分标记记录
  4. 筛选回收:对各个Region的回收价值和成本进行排序,根据用户所期望的GC停顿时间来制定回收计划

内存分配与回收策略

对象的内存分配主要是指在Java堆上的分配,通常会优先分配在新生代,然后经历一系列GC后仍然存活的对象会进入到老年代。少数情况下,一些对象也会直接进入到老年代。

-Xms:设置初始化堆内存,-Xmx设置最大堆内存,设置为相等可防止内存抖动(剩余内存大于70%、小于40%时,自动触发内存扩大或缩小)

1. 对象会优先分配在新生代

新生代划分为一个eden区和两个survivor区(from survivor、to survivor)。初始阶段,新创建的对象会分配给eden区。新生代发生的GC成为minor GC即Young GC,主要分为以下几个过程:

  1. 随着eden区存储的对象不断增多,当eden区剩余空间无法存储新生成的对象时会触发GC
  2. 经过minor GC后仍然存活的对象会进入from survivor区
  3. 当再次触发GC时,会扫描eden区和from survivor区,对这两个区域进行垃圾回收,仍然存活的对象会被复制到to survivor区,同时这些存活的对象年龄加1
  4. 清空eden、from survivor区中的对象,并将from survivor和to survivor区互换
  5. 频繁执行上述过程,当剩余存活对象年龄达到15(默认)时,这些对象会进入老年代,通过参数-XX:MaxTenuringThreshold控制

-Xmn用来设置新生代大小,一般设置为整个堆内存的3/1或者1/4

-XX:NewRatio设置新生代与老年代的堆内存比例

-XX:SurvivorRatio设置eden区和survivor区之间的比例

2. 老年代存储的对象

发生在老年代的GC是major GC,回收速度会比minor GC慢。

上文已经说明了对象进入老年代的一种情况即长期存活的对象会进入老年代,这里再来看看其他情况:

1. 大对象直接进入老年代大对象需要的连续存储空间(如数组)大于新生代剩余空间时,会直接进入老年代。

通过参数-XX:PretenureSizeThreshold设置,大于该参数值的对象会直接进入老年代(避免新生代中大量对象的拷贝,效率低)

注意:PretenureSizeThreshold参数只对部分垃圾回收器有效,比如Serial和ParNew

2. 如果survivor区相同年龄所有对象大小的总和大于survivor空间的一半,年龄大于或等于该年龄的对象可以直接进入老年代,无需等到MaxTenuringThreshold设置的年龄

注意:永久代不属于堆空间,通过参数-XX:PermSize,-XX:MaxPermSize控制大小

3. Full GC

full GC是针对整个Java堆空间进行垃圾回收,包括新生代和老年代,会造成stop world。要尽量避免full GC,它会影响程序的稳定性。

导致Full GC的几点原因:

1. 老年代空间不足从年轻代进入老年代的对象所占空间大于老年代剩余空间大小。eden区调大一些,尽量让对象在新生代minor GC回收,而不是集中在老年代进行major GC,尽量不要创建特别大的对象

2. 垃圾回收算法用的不对比如在老年代使用复制收集算法

3. 永久代空间不足

4. 被HandlePromotionFailure参数强制Full GC

在发生minor GC时,虚拟机会检测之前每次晋升到老年代的平均大小是否大于老年代的剩余空间大小,如果大于,则改为进行full GC。如果小于,则根据HandlePromotionFailure的设置是否允许担保分配内存失败:如果允许失败,则只进行minor GC;反之,则进行full GC。

但是如果发生HandlePromotionFailure失败,则会进行full GC。


关注微信公众号:大数据学习与分享,获取更对技术干货

JVM垃圾回收器、内存分配与回收策略的更多相关文章

  1. JVM探秘:内存分配与回收策略

    本系列笔记主要基于<深入理解Java虚拟机:JVM高级特性与最佳实践 第2版>,是这本书的读书笔记. 内存分配一般关注的是对象在堆上分配的情况,对象主要分配在新生代的Eden区中,如果启用 ...

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

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

  3. JVM学习十 -(复习)内存分配与回收策略

    内存分配与回收策略 对象的内存分配,就是在堆上分配(也可能经过 JIT 编译后被拆散为标量类型并间接在栈上分配),对象主要分配在新生代的 Eden 区上,少数情况下可能直接分配在老年代,分配规则不固定 ...

  4. Java虚拟机内存分配与回收策略

    内存分配与回收策略 Minor GC 和 Full GC Minor GC:发生在新生代上,因为新生代对象存活时间很短,因此 Minor GC 会频繁执行, 执行的速度一般也会比较快. Full GC ...

  5. jvm内存分配和回收策略

    在上一篇中,已经介绍了内存结构是什么样的. 这篇来介绍一下 内存是怎么分配的,和怎么回收的.(基本取自<深入理解Java虚拟机>一书) java技术体系中所提倡的自动内存管理最终可以归结为 ...

  6. JVM的内存分配和回收策略

    对象的Class加载 虚拟机遇到一条new指令时,首先将去检查这个指令的参数是否能在常量池中定位到一个类的符号引用,并且检查这个符号引用代表的类是否已被加载.解析和初始化过.如果没有,那必须先执行相应 ...

  7. JVM 内存分配和回收策略

    对象的内存分配,主要是在java堆上分配(有可能经过JIT编译后被拆为标量类型并间接地在栈上分配),如果启动了本地线程分配缓冲,将按线程优先在TLAB上分配.少数情况下也是直接分配到老年代,分配规则不 ...

  8. JVM:内存分配与回收策略

    Java技术体系中所提倡的自动内存管理最终可以归结为自动化的解决了两个问题:给对象分配内存以及回收分配给对象的内存. 对象的内存分配,往大方向讲,就是在堆上分配(但也可能经过JIT编译后被拆散为标量类 ...

  9. A4. JVM 内存分配及回收策略

    [概述] Java 技术体系中所提倡的自动内存管理最终可以归结为自动化地解决两个问题:给对象分配内存以及回收分配给对象的内存. 对象的内存分配,往大方向讲,就是在堆上分配,对象主要分配在新生代的 Ed ...

随机推荐

  1. 记一次py交易

    讲一个故事 以下故事真实性不保证(你们懂的) 我没说这个是真的 所以不能当做以后别人挑我刺的证据 我只是讲个故事罢了 故事可以是fake 我不会承认这个故事是真的罢了 朋友是某c9高校工科专业 学校培 ...

  2. Vue基础语法(四)

    vue的生命周期钩子函数 所有的生命周期钩子自动绑定this到上下文实例中,因此可以访问数据对property和方法进行运算,这意味着不蹦使用箭头函数来定义一个生命周期方法.参考官方文档,生命周期图 ...

  3. android自带下拉刷新SwipeRefreshLayout

    也是一个布局容器,只有一个子组件,类似scrollView <?xml version="1.0" encoding="utf-8"?> <a ...

  4. 惊呆了!Spring Boot 还能开启远程调试?

    持续原创输出,点击上方蓝字关注我 目录 前言 什么是远程调试? 为什么要远程调试? 什么是JPDA? 如何开启调试? transport server suspend address onthrow ...

  5. 4g物联网模块的原理

    4G DTU模块也可以被称之为是含有第四代移动通信技术的模块,是随着科技不断发展进步下物联网和移动互联网发展下的又一产物.而4G技术包括TD-LTE和FDD-LTE两种制式.集3G与WLAN于一体并能 ...

  6. Docker(1)- 什么是 Docker

    如果你还想从头学起 Docker,可以看看这个系列的文章哦! https://www.cnblogs.com/poloyy/category/1690628.html 备注 这里的概念直接引用官方的, ...

  7. 如何在Debian上安装和使用PHP Composer

    1.条件 shell使用sudo权限访问正在运行的debian系统. 必须安装和配置5.3或更高版本的PHP. 2.在Debian上安装Composer 可以通过运行以下命令从getcomposer. ...

  8. typeerror object of type ‘decimal‘ is not json serializable jsonify

    当使用flask的jsonify返回json数据时,由于数据库有些字段类型使用decimal,而jsonify无法处理 解决方案 导入下面的包即可解决 pip install simplejson

  9. 联发科Mediatek工业路由芯片上网稳定低功耗的Router模块WiFi中继——无线AP定制方案

    Router模块又名路由器模块,是指将路由器的接口类型及部分扩展功能是可以根据实际需求来进行无线接入服务,允许其他无线设备接入,通过局域无线端或联网远程端,进行数据访问,对无线设备进行远程控制.常见的 ...

  10. C++ storage allocation + Dynamic memory allocation + setting limits + initializer list (1)

    1. 对象的空间在括号开始就已经分配,但是构造在定义对象的时候才会实现,若跳过(譬如goto),到括号结束析构会发生错误,编译会通不过. 2.初始化 1 struct X { int i ; floa ...