深入理解Java虚拟机:JVM高级特性与最佳实践之垃圾回收器及内存分配策略 -- 读书笔记...

1.根搜索算法:

Java通过根搜索算法(GC Roots Tracing)来确定对象是否存活,其基本算法是以"GC Roots"的对象为起点向下搜索,搜索所经过的路径为引用链,当一个对象与GC Roots没有任何引用链相连时便认为该对象是不可用的,可以收回.

2.垃圾器收集算法

2.1标记-清除算法(Mark-Sweep)
标记-清除算法分位两个步骤:标记和清除.首先通过跟搜索算法标记出那些对象不可用,然后统一将这些不可用的对象回收掉.
执行过程如下所示:
[img]http://dl2.iteye.com/upload/attachment/0089/6002/97558230-6429-3ea1-835f-1cf7c8fc3d60.png[/img]
标记-清除算法具有两个缺点:一个是效率不高,另外一个是清除后存在大量的内容碎片.这样即使有足够的内存,但是由于内存碎片较多而导致无法为较大的对象分配内存,导致内存不足而不得不提前进行新的内存收集动作.

2.2复制算法
为了解决效率问题,采用复制算法(Copying).这种算法将内存分为相等的两块.每次只是用一块,当这块内存用完之后,就将还存活的对象复制到的另一块内存中,这样内存碎片化的情况就不存在了,只需将指针移到顶端按顺序分配内存即可.这个算法的不好一面就是内存大使用率只有50%.
复制算法的执行过程如下所示:

[img]http://dl2.iteye.com/upload/attachment/0089/6018/291f6b36-6525-31a4-9b30-e39079d55cf7.png[/img]

实际上,现在的商业虚拟机都将复制算法用在新生代中回收内存.但是由于在新生代中的98%对象都是朝生夕死的,存活的对象非常少,所以会将内存分成一块较大的内存Eden(伊甸)和两块相等的Survivor(生存).当回收内存时,会将Eden和一块Survivor存活的对象拷贝到另一块Survivor中.默认情况下他们按照8:1:1的比例进行划分,也即是新生代中可用的内存占90%.当然虚拟机无法保证每次只有不多于10%的对象存活,当Survivor内存不够用时,会需要依赖其他内存(老年代)进行分配担保(Handle Promotion).

2.3标记-整理算法(Mark-Compact)
复制收集算法在对象存活率较高时就要执行较多的复制操作,效率将会变低.更主要的是不想浪费50%的内存,就需要有额外的空间进行分配担保,以应对使用内存所有对象都100%存活的极端情况,所以一老年代一般不直接选用这种算法.根据老年代的特点,有人提出了标记-整理算法.标记过程和标记-清除算法一致,但后续过程不是将不可用对象清除掉,而是将存活对象向一边移动,然后将直接清除端边界外的内存.
标记-整理算法的执行过程如下图所示:

[img]http://dl2.iteye.com/upload/attachment/0089/6120/9bd4669f-5676-3289-8cb8-c986ef2b5705.png[/img]

2.4分代收集算法
当前商业虚拟机都采用"分代收集(Generational Collection)算法",这种算法只是根据对象的存活周期不同将内存划分为几块,一般将Java堆分为新生代和老年代,这样就可以根据各个年代的特点采用最适合的收集算法.在新生代中,每次垃圾收集时都发现有大批对象死去,只有少量存活,那就选用复制算法,只需要付出少量存活对象的复制成本就可以完成收集.而老年代中因为对象存活率高,没有额外空间对他进行分配担保,就必须使用"标记-清除"好"标记-整理"的收集算法.
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值