分代
2个根据以前的经验 得到的假说
- 1.大多数对象活不久
- 2.活了很久的 很难死
这样就把对象分为2类了,
朝生夕死的对象,是一类, 回收比较划算, 优先回收
猜想会活很久的, 万不得已, 才回收
可以用不同的垃圾回收算法,放就不要放在一起, 分开放
前者叫新生代, 后者到老年代
假说
- 3.跨带的引用, 很少
因此, 真的可以只收新生代,
至于老年代对新生代对象的引用,这样处理:
在新生代上 有一个记忆集
, 记录 老年代 哪些区域有对新生代对象的引用
新生代垃圾回收时, 会把记忆集里面记录的老年代哪些有对新生代引用的小块内存, 加入 GC Roots
这样, 虽然增加了 维护 记忆集 的日常成本, 但是比要扫描整个老年代 是划算的
标记-清除
1.标记要回收的
2.回收被标记的
缺点:
空间碎片, 导致后来的大对象会放不下
用复制的 内存分配器 内存访问器 解决, 如
用分区空闲分配链表
, 不要求连续的存储空间
但是内存的访问是最频繁的用户程序操作, 这样影响程序吞吐量,代价太大
标记-整理
适合新生代, 存活率低的
Eden :S1:S2 8:1:1
仅仅10%空间为了放复制的存活对象会被闲置
如果万一不够放 分配担保
:
先借从老年代一点空间, 下次还,就是对象放到老年代去
标记-整理
适合老年代, 存活的很多的
移动式的
代价:
移动存活对象来整理时,
要更新 引用这些对象的地方,
必须STW
网友评论