JVM的GC机制<一>新生代GC

java中GC的对象是堆和永久区
在C++和Java之间隔着一堵由对象的内存手动分配释放和自动回收围成的墙,墙外面的人想进去,墙里面的人却想出来。C++和Java在对内存的管理上有着根本的区别。下面来讲下Java的内存回收机制。
每种高级语言都有着自己相应的内存模型和回收机制。Java的内存是通过GC机制(Garbage Collection)来自动进行回收的,而GC机制是通过垃圾收集器(Garbage Collector)定时对内存(具体来说就是堆,当然也有很少的非堆的部分,主要针对堆来讨论)中的死对象进行回收实现的。在jdk1.7版本中,共有7种垃圾回收器,分别是Serial,ParalleNew,Parralle Scavange,Serial Old ,Paralle Old ,CMS和 G1(具体请看官网说明)。
在具体介绍这些垃圾回收器之前,先讲下JVM对内存的划分。以HotSpot的JVM为例,JVM的堆可以划分为,Young Generation和Tenured Generation,Younge Generation又分为Eden和Survivor区(其中Survivor又分为两个相等大小的区域,即From和To),可由下面两条公式来描述:
Heap= Younge Generation(Eden+Survivor)+Tenured Generation;;
Survivor = From +To;
Young Generation(新生代),顾名思义,是较新的对象所存在的堆中区域,Tenured Generation(老年代)是较老的对象所存在的区域。对象如果存活到一定年龄还未被回收的话,就会从Young Generation移到Tenured Generation,而无用对象则就会在Young Generation中被回收(当然,也有在Tenured Generation中被回收,但大部分情况下都是在Young Generation中被回收)。
HotSpot JVM 又把新生代进一步划分为3个区域:一个相对大点的区域,称为”伊甸园区(Eden)”;两个相对小点的区域称为”From 幸存区(survivor)”和”To 幸存区(survivor)”(From和To总是一样大)。按照规定,新对象会首先分配在 Eden 中(如果新对象过大,会直接分配在老年代中)。在GC中,Eden 中的对象会被移动到survivor中,直至对象满足一定的年纪(定义为熬过GC的次数),会被移动到老年代。
GC分为Minor GC(发生在新生代,代价小,通常几十ms,频繁发生)和Full GC(发生在老年代,代价大,通常在100ms到几s之间,较少发生)。在一次Minor GC过程中,Eden和From区域存活的对象会被移动到To区,如果To满了,那么就会直接移动到老年代,如果连老年代都装不来,那么就会报OutOfMemory错误。但是有个值得注意的地方,也是很多博客中没讲到的问题,From区和To区这两个区域并不是固定的。每次Minor GC后,From区和To区相互对调名字。在下次GC时,To 幸存区会成为From 幸存区。

上图演示GC过程,黄色表示死对象,绿色表示剩余空间,红色表示幸存对象
总结一下,对象一般出生在Eden区,年轻代GC过程中,对象在2个幸存区之间移动,如果对象存活到适当的年龄,会被移动到老年代。当对象在老年代死亡时,就需要更高级别的GC,更重量级的GC算法(复制算法不适用于老年代,因为没有多余的空间用于复制)。

原博客地址

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值