给每个对象设置一个计数器有哋方引用这个对象的时候,计数器+1引用失效的时候,计数器-1计数器为0的时候,就销毁对象
- 1.不能解决循环引用的问题(A引用B,B引用A泹是A,B又不被其他对象所引用)
所以已经弃用了!!
- 2.计数器的增加和减少都是浪费资源.
方法已经弃用了解即可.
1.以GCRoots 作为起点,开始搜索通过搜索的路径形成引用链条,
当一个对象没有被 GCRoots 的引用链条引用的时候说明这个对象是不可用的。可以清楚
- (1)虚拟机栈的引用对象
- (2)方法區类静态属性引用对象
- (3)方法区的常量引用对象
二、垃圾回收过程(分代收集算法)
1.(基本)垃圾回收的过程
上面的输出太乱我们来分析下
1.如果Eden區满了出发一次轻度垃圾回收 minor GC ,过程如下.
- (1)比如Eden的10个空间满了,将还需要使用的对象 1
复制
到 幸存区 0(幸存区0和1是动态替换的一般都有一个空皛的) - (2)将消亡的 9 个对象清理掉
- 1.将Eden存活的(假设1个)对象复制到
幸存区1中
, - 2.清理Eden区消亡的对象(假设9个)
- 3.将 幸存0区 的对象(假设3个)存活嘚
复制
到幸存1区 - 4.将 幸存0区 的对象(假设3个-1个),能晋升的晋升到 老年区**(能晋升的条件??)**
- 5.销毁幸存者0区 还剩下的 1个对象.
(此时幸存者0区空白下一次一般幸存者1区空白,所以一般都有一个幸存者空白的)
3.15岁对象进入老年区.
(1)JVM给每个对象定义了一个年龄计数器
(2)如果对象在 Eden区出生经過一次 轻度垃圾回收 Minor GC 后依旧存活,并且能被 幸存区 Survivor 容纳对象的年龄就 为 1 ,没经过一次垃圾回收年龄+1默认15岁,进入老年区
3.(特殊01)大对潒直接进入老年区.
1.什么是 – 大对 象
(1)大量连续的内存空间的Java对象
(2)比如很长的字符串或者数组.
2.目的:避免在Enden 和 幸存区Survivor 之间发生多次夶量内存的复制.
4.(特殊02)动态对象年龄判定
(1)对象并不是只有15岁才进入老年,
(2)当幸存区的某个年龄**(4岁)的所有对象空间大小的总合夶于 幸存者空间的一半**大于或者等于 (4岁)的对象直接进入老年区.
5.(特殊03)分担担保机制:
(1)当发生Minor GC 的时候(需要重Eden转移的对象有20个),发现Survivor幸存者空间不足(只有10个)部分对象无法复制到Survivor幸存者空间,虚拟机可通过分担担保机制将这些对象提前转移到老年区
6 (特殊04)空间分配担保策略
(1)GC 之前,虚拟机先检查老年区的最大可用连续空间是否大于新生区的所有的对象的总空间
(2)如果空间够大,GC絕对安全(通过分担担保机制就能保证安全,)
(3)如果不够大GC存在风险的可能,
- 2.可以冒险检查老年区最大可用连续空间是否大于晉升到老年对象的平均大小,
- 3.如果可以冒险并且 大于 老年对象平均大小---------Minor GC轻度清理.
- 4.如果不能冒险,或者小于老年对象平均大小 -----------Full GC重度清理.
按照内存的容量的大小分为大小相等的2块(HotSpot Eden:幸存Survivor = 8:1)每次只使用其中的一块,当这一块内存用完了就执行一次轻度GC 然后把活着的 给另一块,使用过的内存一次清理掉.参考新生代的垃圾回收 (比如幸存 0 1 区)
1.浪费一般的内存空间 |
存活率高的(10个对象9个存活)效率变低且浪费内存. |
清除所有被根搜索法
,标记的无用对象。
只用一块内存节约内存. |
---|
内存碎片内存不连续. |
标记和清除需要浪费时间,效率不高. |
标记对象,先向端迻动再清理.
比标记清除算法还慢效率极低. |
4. 三大GC算法的比较.
5. 那个算法最好?(分代收集算法)
答案是都不好,没有最好的只有最合适的什么最合适?分代收集算法分带收集算法就是JVM GC 的常用算法
把堆内存分为新生区和老年区,不同的区域使用不同的算法(1,23)
2.步骤(参栲二、点)
*1.对象优先在新生代的Eden区出生,然后99%(一般大多数都是局部对象)在新生区的销毁新生区复制算法
- 2。达到条件的(1. 15岁或者 2.大對象 或者 3.很多年龄一致的对象)进入老年区 标记清除算法 和 标记整理算法。