垃圾收集算法

判断对象是都还活着:

 - 引用计数算法(**已经淘汰**)
 - 可达性分析算法,GCRoot

最基础的算法:标记-清除

分为标记和清除两步。

就像清理垃圾,要从头开始一个一个的贴上待清除的标签,贴完了再一个一个的清理掉。

这是很自然就能想到的一种清理方式。
在生活中也是这样,看看家里哪些东西不需要了,
盘点一下,不要的直接拿到外面。

这种方式有两个大问题:**从时间和空间两个角度来看**
    -- 很费时间
	-- 造成内存碎片

改进:复制算法

为了解决上面 标记清除 算法存在的劣势,一种叫做 复制 的收集算法出现了。

他将可用内存容量划分为大小相等的两块,每次只使用其中一块。

当这一块内存用完了,将其中还活着的对象复制到另一块内存上面,
然后再把使用过的内存空间一次清理掉。

这样每次清理都是把 整个半区 直接清空,
给新的对象分配空间的时候也不用再考虑空间碎片的情况。

这种算法的代价是将内存缩小为了原来的一半。

实际应用:新生代采用的垃圾回收算法思想


现在的商业虚拟机都采用这种收集算法来回收新生代

新生代中的对象98%"朝生夕死"的,并不需要按照11的比例来划分内存空间
实际是将内存划分为一块较大的Eden 空间和两块较小的Survivor空间

每次使用Eden和一块Survivor。
当回收时,将二者中还活着的对象一次性复制到剩下的那一块Survivor空间中。
HotSpot 虚拟机默认的Eden:Survivor:Survivor 比例是811
也就是每次新生代中可用的内存空间为整个新生代容量的80%+10%

如果剩下那一块Survivor空间没有足够的空间存放上一次新生代收集下来的存活对象
这些对象将直接通过分配担保机制进入"老年代"

改进:标记–整理算法

 复制收集算法在对象存活率较高时就要进行较多的复制操作,
 效率就会变低,
 更关键的是,如果不想浪费50%的空间,
 就需要有额外的空间进行分配担保,
 以应对被使用的内存中所有对象都100% 存活的极端情况,
 所以在老年代一般不能直接选用复制收集算法。

 根据老年代的特点,人们提出了一种”标记--整理“算法,
 标记过程和之前一样,但之后的操作不是对已标记的对象进行回收,
 而是让所有存活的对象都向一端移动,然后直接清理掉端边界之外的空间。

分代收集算法

当前商业虚拟机的垃圾回收,都采用分代回收的方法。
这种算法的核心思想是根据对象存活周期的不同将内存划分为几块。
一般是把java堆分为新生代和老年代。
这样就可以根据各个年代的特点选择最合适的垃圾回收算法。

在新生代中,每次垃圾回收时都发现有大批对象死去,只有少量存活,
那就选用复制算法,只需要付出少量存活对象的复制成本就能完成垃圾回收。

而老年代中因为对象存活率高、没有额外空间对他进行分配担保,
就要看情况选择 "标记-清除" 或者 "标记-整理” 算法。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值