Java GC 内存回收机制详解(三)内存回收算法

五. 没有包治百病的通用内存回收算法

现代面向对象编程的方式,向程序员屏蔽了背后内存分配和回收的细节。程序员一半不会考虑内存效率问题,而把中心放在业务逻辑上。这种方式,决定了程序员的使用内存的习惯:用的时候分配,不用的时候赋Null值。所以很多对象,尤其是临时对象,寿命都很短,在使用完成后,就可以被回收了。不过,也有很多对象,生命周期较长。上文中提到,GC的回收算法,是和当前对象的数目成线性关系,对象越多,效率约低下。

因此,对生命周期不一样的所有对象,均一视同仁,势必效率低下,不是很好的做法。

六. 引入次代概念

一切都因为效率。

实际上,GC的设计者,根据对象的活跃程度,把对象分为了:青年代和老年代。针对青年代和老年代使用不同算法,在不同的时机收集,来提升整体效率。如下图




  • Eden区是分配对象的区域,这里是对象的出生地。
  • Survivor(S0和S1)是minor gc后,存储存活对象的区域。
  • Eden以及Survivor(上图中的S0和S1)共同组成New Generatiton(或者叫Young space,青年代)
  • Old Generationd(老年代)区域存储长时间存活的对象。

七 . 内存回收算法

GC的回收流程简述如下:
  • 通过GCRoot和可达链,标记出堆中活着的对象;
  • 定期调整活对象的位置:把青年代里活的很长的对象移动到老年代;
  • 释放死对象占用的资源:青年代条件满足随时收集,老年代满了才去收集;
  • 在青年代区域(Young space)里回收,叫做minor GC;
  • 在老年代区域(Old Generationd)里回收,叫做Major GC;
  • 全部区域回收,叫Full GC。

青年代的GC算法有以下三种:
  • Serial:简单高效的收集器;
  • ParallelScavenge:采用Copy算法的并行收集器(吞吐量优先的);
  • ParNew:Serial收集器的多线程版本。
老年代的GC有以下三种:
  • Serial Old:Serial的老年代版本;
  • Parallel Old:Parallel Scavenge的老年代版本;
  • CMS:并发低停顿收集器(重视相应速度);

下面,已Serial为例,描述一下垃圾回收的过程:
回收前
回收后:

三个要点:
1. Eden区域中,非活动对象被释放,活动对象迁移到Survivor Spaces中,被标记为to的区域;
2. Survivor Spaces区域中,被标记为from区域中非活动对象被释放,活动对象迁移到两个地方:
1)活动对象存活时间足够长,被迁移到Old Generation区域中;
2)活动对象存活时间不足够长,被迁移到Survivor Spaces中,被标记为to的区域;
3. Old Generation区域,在满的时候,才会触发Old Generation GC算法。
*注:
1. Eden是对象诞生的地方,每次GC完成之后,此区域为空;
2. Survivor Space有两个(S0,S1),青年代对象到老年代对象过度区域。每次GC完成之后,有一个区域为空,并且to/from标记交换。

八. 附录
1. Minor / Major GC触发的时机
下面是简单描述,具体触发时机,和两个区域选择的GC实现有关系:
  • 对象在Eden Space完成内存分配时触发;
  • 当Eden Space满,再创建对象,因为空间不足触发;
  • 当Old Space被放满之后,进行Full GC

2. 根治循环引用
GC Root在对象图之外,是特别定义的“起点”,不可能被对象图内的对象所引用。
和引用计数方式不同,一个对象的内存是否释放,只和是否有相对应的Root直接或者间接引用相关(可达),与是否发生了循环引用,没有任何关系。

3. 关于内存碎片

4. 理解引用(句柄 和 指针)
引用有两种方式,句柄和指针:
1) 指针引用
指针非常容易理解,即在变量里保存的是对象的地址。
指针,直接把对象的地址,暴露给外部,相对来说不是特别安全。
如下图:

2) 句柄引用
句柄,实际上是在指针的基础上,引入了一个中间层。
系统维护了一个句柄池,真正的指针保存在句柄池里。
而引用中存放的是句柄(或者句柄地址),通过句柄,间接的到指针,从而对对象进行内存访问。


  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值