`
bit1129
  • 浏览: 1050445 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

【JVM三】新生代垃圾回收

    博客分类:
  • JVM
 
阅读更多

JVM将堆空间划分为新生代和老年代,如此花费是为了更高效的进行垃圾回收。

  • 简化创建对象的内存分配,新创建的对象都会放到新生代
  • 针对新生代和老年代的特点,使用不同的垃圾回收策略。

面向对象编程中的对象,广泛的研究表明,对象大多是朝生夕死,并且已经在JVM上存活较长时间的对象很少引用新生的对象,基于这两方面的原因,把新生对象放到新生代,GC可以更快查找可以被回收的对象

 

新生代的区域划分

 

Sun/Oracle的HotSpot JVM将新生代做了细分,HotSpot将新生代划分为3个区域,较大的区域称为"Eden",两个较小的幸存者空间(survisor spaces),这两个幸存者空间一个称为From,另一个称为To。一轮GC过程中,Eden活下来的对象将被移动到幸存者空间,这些对象将在幸存者空间呆上一段时间(呆在这个阶段期间,这些对象可能要经历几次GC),如果几次GC后,这写位于幸存者空间的对象依然存活,那么它们将被移动到老年代。因此,幸存者空间就是给进入新生代的对象更多点呆在新生代的时间。每次GC时,Eden和幸存者空间都要被扫描以确定哪些对象要被回收。

 

新生代垃圾回收的过程

基于新生代中的对象在经历过一次GC后,大多数对象都会被回收的假设,新生代垃圾会采用复制的策略:

1. 在GC刚开始的时候,Survior的To空间是空的,对象只能存在于Eden或者From。

2. 随着GC的进行,

    2.1 Eden空间依然被引用的对象将被移动到To空间。

    2.2 From空间,这个空间中依然被引用的对象的处理依赖于它们的存活了的多少时间。如果它们的存活周期没有达到某个阀值(„tenuring threshold,表示经历了几次GC依然存活),那 么它们也要被移动到To,否则它们将被移动到老年代。

3. 当这个copy的过程结束后,Eden和From空间中的对象是可被回收了(新生代所有存活下来的对象要么去了To,要么去了老年代)。在Eden,From向To空间移动的过程中,To空间有可能满了,那么剩下的对象,将直接移动到老年代。

4. 最后一步,From和To交换角色,因此在下一轮GC开始时,To是空的,而From则包含了所有新生代上轮GC时存活下来的对象。

 

下图所示是新生代GC开始时的状态以及GC结束时的状态

 

 

 新生代GC过程总结

 

刚创建的对象在放在Eden,然后在新生代GC时,可能被移动到To空间。如果对象在几轮年轻代垃圾回收之后依然存活,那么它最终会被移动到老年代。对老年代的垃圾回收需要更大的代价,这需要更高效的GC算法(老年代不能使用简单的复制,因为没有空间可以复制了)。因此,新生代的堆空间容量是非常重要的,如果新生代空间太小,那么新生代的对象很快就会被移动到老年代(老年代垃圾回收的代价要远远超过新生代);反之,如果新生代过大,那对于长时间存活而最后到达老年代的对象,就会导致很多不必要的复制(每轮GC都要复制)。一次需要在新生代空间大小上取一个合适的值,以适应特定的应用。JVM提供了一系列的选项用于对新生代的容量调整。

 

 

新生代相关的JVM选项

 

 -XX:NewSize and -XX:MaxNewSize

 

-Xms和-Xmx分别表示堆内存的最小值和最大值,--XX:NewSize和-XX:MaxNewSize分别表示新生代的最小值和最大值。需要注意的是,--XX:NewSize和-XX:MaxNewSize设置的新生代的容量,新生代设置的越大,那么老年代则越小。实际中,基于稳定性考虑,新生代的大小应该小于老年代的堆大小,因为在最糟糕的情况下,GC有可能将新生代所有的对象移动到老年代,因此,新生代堆的大小上限是-Xmx/2。
基于性能的考虑,新生代的初始大小设置为--XX:NewSize,这个值的设置也是一个参考值。

 

 -XX:NewRatio

 

 通过-XX:NewRation这个选项来显式的指定新生代和老年代的大小比例。通过这种相对大小的方式,可以让JVM在运行时由于动态调整堆大小时,动态的调整新生代的大小。-XX:NewRatio=3表示老年代是新生代的3倍,即新生代占堆空间的1/4,而老年大则占堆空间的3/4.

 

如果既设置了-XXNewSize,-XX:MaxNewSize,也设置了-XX:NewRatio,那么JVM首先尝试将新生代的大小按照新老比例进行设置(-XX:NewRatio),但是最小值不能低于-XXNewSize,最大值不能超过--XX:MaxNewSize

 

 


 -XX:SurvivorRatio

 

-XX:SurvivorRatio用来设置在新生代内部,Eden区与Survior区的大小比例关系。比如-XX:SurvivorRatio=10表示Eden区域的大小时Survivor的From/To区域的10倍,也就是说,Eden占新生代的10/12,From和To各占1/12。

 

-XX:+PrintTenuringDistribution

 

使用-XX:+PrintTenuringDistribution这个选项是让JVM在每次新生代GC时,打印出survivor区域的对象的存活周期,比如:

 

Desired survivor size 75497472 bytes, new threshold 15 (max 15)
- age   1:   19321624 bytes,   19321624 total
- age   2:      79376 bytes,   19401000 total
- age   3:    2904256 bytes,   22305256 total

 

第一行信息是"To"空间的大小约75MB。新生代经历15次GC依然存活的,将从survivor区域移动到老年代。

 

下面的几行则显示了经历了几次新生代GC的对象的空间利用情况。例子中的数目表明:大约19M的对象经历了一次GC,大约79KB经历了两次GC,大约3MB经历了3次GC。在每行的最后,是在这个age范围内所包含的所有对象占用的空间,比如对个age 2,它包含的总数包括age 1对象占用的空间加age 2对象占用的空间。因此,"total"这个值意味着"To"空间当前大概包含22M对象数据。因为”To“空间的可用空间是75MB并且threshold是15,因此,当前没有对象需要移动到老年代。

 

再来看一下新一轮GC的情况:

 

Desired survivor size 75497472 bytes, new threshold 2 (max 15)
- age   1:   68407384 bytes,   68407384 total
- age   2:   12494576 bytes,   80901960 total
- age   3:      79376 bytes,   80981336 total
- age   4:    2904256 bytes,   83885592 total

 

比较两组数据,可以看到如下信息

1. 可见原来的age 1变为后面的age 2, 原来的age 2变为后面的age 3, 原来的age 3变为后面的age 4

2. 原来age1大概有19M,而后面的age2只有12M,也就说,这轮GC,有大概7M的内容被回收。

3. ,新一轮GC增加了大概68M的新增对象进入age 1。也就说,在这一轮GC中,JVM从Eden区移动了大概68M的数据进入To空间

 

4.在上面的示例中,To空间已经达到将近84M,超过75MB。因此,JVM把tenuring threshold从15降低到2,因此,接下来新一轮GC,那么To空间的对象,要么生命到期而被回收,要么进入老年代。

 

注:tenuring threshold参数的含义是控制对象经历多少次Minor GC才从新生代晋升到老年代代

 

-XX:InitialTenuringThreshold, -XX:MaxTenuringThreshold and -XX:TargetSurvivorRatio

 

【TBD:这段需要重写】

-XX:+PrintTenuringDistribution这个选项的输出结果可以由多个选项进行调整。通过-XX:InitialTenuringThreshold 和-XX:MaxTenuringThreshold可以设置tenuring threshold的初始值和最大值。并且,我们也可以通过-XX:TargetSurvivorRatio来在新生代GC结束时,用于指定"To"的目标使用率。比如同时设置如下两个选项,

-XX:MaxTenuringThreshold=10 -XX:TargetSurvivorRatio=90设置了tenuring threshold的上限是10,并且指定了"To"空间的目标使用率是90%。如下两个场景:

1.如果-XX:+PrintTenuringDistribution显示的结果表示它们在最后达到最大tenuring threshold前经历了很多次GC,通常意味着-XX:MaxTenuringThreshold的设置偏大。

2.

 

 

The tuning knobs shown in the output of -XX:+PrintTenuringDistribution can be adjusted by various flags. With -XX:InitialTenuringThreshold and -XX:MaxTenuringThreshold we can set the initial and maximum value of the tenuring threshold, respectively. Additionally, we can use -XX:TargetSurvivorRatio to specify the target utilization (in percent) of “To” at the end of a young generation GC. For example, the combination -XX:MaxTenuringThreshold=10 -XX:TargetSurvivorRatio=90 sets an upper bound of 10 for the tenuring threshold and a target utilization of 90 percent for the “To” survivor space.

While there are different approaches to use these flags to tune young generation behavior, no general guideline is available. We restrict ourselves to two cases that are pretty clear:

  • If the tenuring distribution shows that many objects just grow older and older before finally reaching the maximum tenuring threshold, this indicates that the value of -XX:MaxTenuringThreshold may be too large.
  • If the value of -XX:MaxTenuringThreshold is larger than 1 but most objects never reach an age larger than 1, we should take a look at the target utilization of “To”. Should the target utilization never be reached, then we know that all young objects get collected by the GC, which is exactly what we want. However, if the target utilization is frequently reached, then at least some of the objects beyond age 1 have been moved into the old generation, and maybe prematurely so. In this case, we can try to tune the survivor spaces by increasing their size or target utilization.
 
 
 
 
 
 
 
 
 
 
 
 
 

 

 

 

 本文参考:https://blog.codecentric.de/en/2012/08/useful-jvm-flags-part-5-young-generation-garbage-collection/

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

  • 大小: 839.6 KB
分享到:
评论

相关推荐

    一文了解JVM全部垃圾回收器,从Serial到ZGC

    对象搜索算法与回收算法介绍了垃圾回收的基础算法,相当于垃圾回收的方法论。接下来就详细看看垃圾回收的具体实现。上文提到过现代的商用虚拟机的都是采用分代收集的,不同的区域用不同的收集器。常用的7种收集器,...

    JVM垃圾回收与调优详解1

    1.JVM内存分配与回收1.1 对象优先在Eden区分配大多数情况下,对象在新生代中 Eden 区分配 2.如何判断对象可以被回收堆中几乎放着所有的对象实例,对

    JVM垃圾回收机制(GC)

    JVM垃圾回收机制(GC) 引入:我们都知道,栈内存中方法运行完毕后会有弹栈的操作,不会产生垃圾,而堆内存中却没有这种操作,当堆内存中很多无用的成员变量、对象等等积压到一定程度时,就会发生堆内存溢出的一个错误...

    JVM垃圾回收与调优详解(1)1

    1.JVM内存分配与回收1.1 对象优先在Eden区分配大多数情况下,对象在新生代中 Eden 区分配 2.如何判断对象可以被回收堆中几乎放着所有的对象实例,对

    Java新生代老年代的划分及回收算法

    当前JVM对于堆的垃圾回收,采用分代收集的策略。根据堆中对象的存活周期将堆内存分为新生代和老年代。在新生代中,每次垃圾回收都有大批对象死去,只有少量存活。而老年代中存放的对象存活率高。 这样划分的目的是...

    超硬核!!!一篇文章搞定整个JVM的垃圾回收系统

    JVM的垃圾回收机制JVM的垃圾回收机制1 什么是垃圾回收机制2 finalize方法作用3 新生代、老年代、永久代(方法区)的区别3.1 为什么要这样分代:3.2 Minor GC、Major GC、Full GC区别及触发条件4 如何判断对象是否存活...

    Java最常见200面试题以及解析

    205. 新生代垃圾回收器和老生代垃圾回收器都有哪些?有什么区别? 新生代回收器:Serial、ParNew、Parallel Scavenge 老年代回收器:Serial Old、Parallel Old、CMS 整堆回收器:G1 新生代垃圾回收器一般采用的...

    JVM调优与内存管理总结

    JVM内存调优,java内存管理总结。包含新生代、老年代等详解。还有垃圾回收收集器详解。

    JVM内存模型架构图-新生代-老年代-永久代

    永久区:存储的是java的运行环境或类信息,这个区域不存在垃圾回收,关闭jvm就会释放内存 一个启动类加载大量的jar包。tomcat部署太多应用。内存满了就oom jdk1.6之前:永久代,常量池是在方法区 jdk1.7去...

    java面试题.docx

    新生代垃圾回收器和老生代垃圾回收器都有哪些?有什么区别? 常用的 JVM 调优的参数都有哪些? -Xms2g:初始化推大小为 2g; -Xmx2g:堆最大内存为 2g; -XX:NewRatio=4:设置年轻的和老年代的内存比例为 1:4; -XX:...

    成为JavaGC专家上(3)—深入浅出Java垃圾回收机制

    在第二篇《》,我解释了JVM实际上是如何执行垃圾回收的,我们如何监控GC,以及那哪些具可以让我们的工作更快,更高效。在第三篇文章中,我们会基于实际的例子来解释一些优化GC的最佳实践。我认为在阅读本篇文章之前...

    21天学会Java之(Java SE第四篇):Java虚拟机、垃圾回收机制

    文章目录Java虚拟机(JVM)JVM的基本结构类加载机制类的生命周期类加载器的种类类加载机制运行时数据区(内存分析)垃圾回收机制新生代(Young Generation)老年代(Old Generation)元空间(Meta Space) Java虚拟机...

    钻研JAVA虚拟机 全面掌握JVM JAVA虚拟机深入浅出实战课程 视频附带课程代码

    ├─(9) 0809_【了解】垃圾回收算法.mp4 ├─(10) 0810_【了解】串行垃圾收集器.mp4 ├─(11) 0811_【了解】并行垃圾收集器.mp4 ├─(12) 0812_【了解】CMS垃圾收集器.mp4 ├─(13) 0813_【掌握】G1垃圾收集器.mp4 ...

    JVM参数设置详细说明

    指定在New Generation使用parallel collector,并行收集,暂停,app threads,同时启动多个垃圾回收thread,不能和CMS gc一起使用。系统吨吐量优先,但是会有较长长时间的app pause,后台系统任务可以使用此 gc b: -...

    JVM原理与调优实战下载即用

    这样的好处是可以减少程序运行时垃圾回收次数,从而提高效率。 初始堆值和最大堆内存内存越大,吞吐量就越高, 但是也要根据自己电脑(服务器)的实际内存来比较。 最好使用并行收集器,因为并行收集器速度比串行吞吐量...

    重磅2023年最新JAVA核心知识整理从基础到精通完整教程-283页全面试题解析学习资料涵项目源码-20231120.pdf

    2.4.垃圾回收与算法 2.4.1.如何确定垃圾 2.4.1.1.引用计数法 2.4.1.2.可达性分析 2.4.2.标记清除算法(Mark-Sweep) 2.4.3.复制算法(copying) 2.4.4.标记整理算法(Mark-Compact) 2.4.5.分代收集算法

    JAVA面试核心知识点283页

    1.目录 1 2.JVM 19 2.1. 线程 20 2.2.JVM 内存区域 21 2.2.1.程序计数器(线程私有) 22 2.2.2.虚拟机栈(线程私有) 22 ...2.4.垃圾回收与算法 26 2.4.1.如何确定垃圾 26 2.4.1.1.引用计数法 26 2.4.1.2

Global site tag (gtag.js) - Google Analytics