Java虚拟机2:jvm堆分代

写在前面的话:本文讨论的虚拟机内存分代,均指HotSpot虚拟机。

 

jvm的内存分代策略:

java虚拟机根据对象存活的周期不同,把堆内存划分为几块,一般而言就是:新生代,老年代,永久代。

 

那为什么要分代?

堆内存是虚拟机管理的内存中最大的一块,也是垃圾回收最频繁的一块区域,程序所有的实例对象都是存放在堆内存中的。给堆内存分代,是为了提高对象内存分配和垃圾回收的效率。假如堆内存没区域划分,那么所有的新创建的对象和生命周期很长的对象都将放在一起,随着程序的执行,堆内存需要频繁的进行垃圾回收,而每次垃圾回收,都要遍历所有的对象,这个性能是很低下的,会影响GC的效率。

将堆内存分为新生代,老年代和永久代,就能提高GC的效率,具体提高效率的原因是:

新创建的对象会在新生代中分配内存,经过多次回收后,依旧存活下来的对象会存储到老年代中,静态属性,类信息等存放在永久代中(和方法区存的内容差不多)。

  • 新生代中的对象存活时间比较短,只需要在新生代内存区域中进行GC;
  • 老年代中对象生命周期比较长,内存回收的频率相对较低,不需要频繁的进行GC;
  • 永久代回收效果很差,因为都是静态属性,类信息等,一般不进行GC;

对于新生代和老年代的GC特点,还可以采用不同的GC算法对其进行垃圾回收,因此,堆内存分代,可以提高GC的性能。

 

新生代,老年代,永久代就是最大粒度的内存划分了吗?

 

新生代是否有垃圾回收?

既然提出了这个疑问,那说明答案应该就是否定的了。

java虚拟机将内存划分为新生代,老年代,永久代。永久代是HotSpot虚拟机特有的概念,其他虚拟机没有永久代的概念,而且局官方文档的备注,jdk1.7以后已经开始有意去去除“永久代”了,把原本放在永久代中的字符串常量池移出,放在方法区。

下面的图,是堆内存的大致划分:

备注:图中的年轻代和文中说的新生代是一个概念

jvm堆内存划分的新生代中,又划分了三个区域:如图所示,分别是:Eden,From,To三个区域。

三个区域的内存大小比例为:Eden:From:To=8:1:1

加个说明:不同的大拿写的书中或者译文中,对From,To这两个区域有不同的称呼,有的叫survivor0,survivor1,也有的叫S0,S1.

这三个区域大小划分,也是前辈先驱经过各种计算,算法推导出来的,过程我也不知道,结果就是,新生代中采用复制算法,进行垃圾回收,这个比例可以充分利用内存空间。

那复制算法具体是怎么样的流程呢或者怎么样触发的呢?

首先,新创建的对象都是在Eden区域分配(大对象不是在这个区域,而是直接放在了老年代),当Eden区域没有足够的内存空间进行分配时,虚拟机就会发起一次Minor GC。GC开始之前,对象只会存放在Eden区域和From区域(survivor0),To区域(survivor1区域)是空的。GC开始时,Eden中的所有存活对象都会被复制到To(survivor1区域),而From区域(survivor0区域)中,依旧存活的对象,会根据他们的年龄值决定他们的去向,年龄值达到阀值(默认是15,新生代中的对象,每经过一次GC,年龄值就会加1,并且将这个年龄值储存在对象的header中)的对象,将会被移动到老年代中,没有达到阀值的对象,也会被复制到To区域(survivor1区域),接着清空Eden区域和From(survivor0)区域。这个时候,所有经历这次GC依旧存活的对象都在To区域(survivor1)中,接着,From和To连个区域交换角色,From成为了To区域,To成为了From区域,这样,此时的To区域又是空的了。具体过程如下图所示:

第一步:GC开始前的状态

第二步:GC开始,将Eden中存活的对象复制到To区域,将From区域中存活且年龄值未到阀值的对象复制到To区域。将From区域中存活且年龄值达到阀值的对象移动到老年代。

第三步:清空Eden区域和From区域

第四步:将From区域与To区域的角色互换(这可能就是From与To区域大小1:1的原因)

经过以上四步,新生代中的一次采用复制算法的Minor GC(次收集),就这样完成了。

 

老年代是否有垃圾回收?

老年代中的对象生命周期较长,存活率较高,因此GC的频率相对较低,而且GC的速度也比较慢。

当老年代区域内存不足以分配时,就会触发Full GC,即全收集。

 

永久代是否有垃圾回收?

永久代存储类信息,常量,静态变量,即时编译器编译后的代码等数据,对这一区域而言,java虚拟机规范指出,可以不进行垃圾回收。

 

 

如有什么不对的地方,请指正。

 

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值