前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Java的分代式GC

Java的分代式GC

作者头像
海纳
发布2018-03-02 14:35:20
8690
发布2018-03-02 14:35:20
举报
文章被收录于专栏:海纳周报

要说理解JVM的垃圾回收,什么引用计数,Copy GC,mark & compaction好像都不是必须要掌握的东西。真要说对普通的Java程序员比较重要的东西,我觉得必须得有分代式垃圾回收。

jstat的输出格式

我们在遇到Java进程比较卡的时候,往往第一个想到的就是使用 jstat 的 GC 相关选项查看一下进程的GC状态。

如上图所示,我们使用gcutil来观察Java堆使用的情况。gcutil打印出的数字分别代表了某一个区域的内存使用的百分比。

  • S0,S1,两个survivor区域,可以看到它们的使用率为0
  • E,代表eden,这是年轻代用于分配新的对象的区域。
  • O,代表老年代,这是我们今天要重点讲的内容。
  • M,代表metaspace,这块内容以后再讲(也有可能永远不再讲了,看情况)
  • CCS,压缩使用比例。可以先不管这个。这个和使用压缩指针有关系。可以使用-XX:-UseCompressedOops关掉压缩的功能,这一项就不再打印了。
  • YGC,年轻代回收的次数。
  • YGCT,年轻代回收所使用的时间。由于年轻代的回收使用copy GC。会让所有Java线程都停顿下来,所以这一项就是指用于年轻代回收的时间。
  • FGC,这一项就比较复杂了。在不同的GC组合中代表不同的意义,后面会详细讲到。
  • FGCT,与上面的FGC一定样的,字面意思是full gc time,但在不同的GC选项下,意义有所不同。
  • GCT,一般来说,等于YGCT与FGCT之和。

好了,我们一再地遇到年轻代和老年代的叫法,它们到底是什么东西呢?

根据对象生命周期所做的GC优化

一个Java对象,存活的时间不同,则它适用的GC算法就会有所不同。比如说系统中的大多数对象的存活时间都很短,那么Copy GC就会很高效,因为每次GC,要保存的存活对象会很少。然后大多数内容都会在一个巨大的空间里集中释放掉。但如果大多数对象的存活时间很长,那么Copy GC就不再高效了,因为每次要搬运太多的内容。这个时候不移动对象的引用计数法或者mark sweep法就会很高效了。

基于这样的观察,人们提出了一种分代式的垃圾回收策略。

把空间划分成年轻代和老年代两块。创建新的对象总是先在年轻代里创建,当年轻代空间不足了,就会触发年轻代的GC,我们称之为young GC,经过一次YGC,对象的年龄就加1,当对象的年龄达到一个阈值时,这个对象就可以进入老年代了。

可以看到,年轻代总是会比老年代先满,年轻代的回收也更频繁。如果能撑过多次YGC的,这种对象的生命周期往往会非常长(例如某些全局单例Config之类的),那么把它们放到老年代,避免在YGC时被拷来拷去是能够有效地提升GC效率的。

一个对象从年轻代进入老年代,叫做晋升(promotion)。晋升这个词我们后面会一再地重复它,它是Java分代GC最容易引发问题的地方。

分代式GC与前边所讲的Copy GC,Tracing GC是不同的,它不是一种单独的GC算法。年轻代或者老年代要使用前边所讲的GC算法的某一种,这样的话,分代式GC就相当于是两种不同的GC算法的组合了。

后面的文章我会逐个介绍年轻代和老年代所使用的不同的GC算法。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2018-01-31,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 HinusWeekly 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • jstat的输出格式
  • 根据对象生命周期所做的GC优化
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档