JVM浅出篇之对象存活算法和GC算法-小白成神之路

1.对象存活算法:

1.1.引用计数算法:

缺点:不能解决循环引用问题。
在这里插入图片描述
循环引用造成的问题:
在这里插入图片描述
内存泄漏:内存存在不可被GC的对象。
内存溢出:内存存在不可被GC的对象不断堆积导致即使创建了很小的对象也不能被装入。

1.2.可达性分析算法/根搜索算法:

GC Roots:
1.虚拟机栈的栈帧的局部变量表所引用的对象。
2.本地方法栈JNI所引用的对象。
3.方法区静态变量和常量所引用的对象。
在这里插入图片描述

2.什么时候进行垃圾回收?

  1. 当eden区或者s区不够用。
  2. Old区空间不够用。
  3. 方法区空间不够用。
  4. System.gc();手动通知JVM要回收对象,但回不回收还要看JVM,同System.gc();还会占用操作系统资源,降低效率。

3.GC算法(基于对象存活算法):

3.1.标记/清除算法:

当堆满时,GC线程触发,业务线程停滞(STW,Stop
the work)。

3.1.1标记/清除过程:

标记:遍历所有的GC root,将所有的GC root以及所有的引用(可达)标记。
清除:遍历整个堆将所有的没有标记的清除。
在这里插入图片描述
在这里插入图片描述

3.1.2.标记/清除算法过程内存变化图解:

在这里插入图片描述

3.1.3.STW来源:

假如GC线程和业务线程并行,会发生什么不符合我们预期的情况?

  1. 用户线程产生了一个新对象并在遍历标记的时候标记了,同时与之前的未标记的对象维持着可达性关系(但该对象之前在遍历标记因没有引用指向而未被标记),就会导致不该回收的被回收了。
  2. 本来被标记的又未被标记了,这就导致了该回收的不被回收。
    分析:所有都是因为GC线程和业务线程并行运行,不断抢占cpu资源互相切换导致的。
    解决:并行变串行,即运行GC线程就不运行业务线程,运行业务线程就不运行GC线程。

3.1.4.标记/清除算法缺点:

1.遍历标记整个堆,效率低下(解决方法:分代)。
2.内存碎片化,维护空闲列表,开销大(解决方法:存活对象移动到另一块内存有序排列)。

3.2.标记/整理算法:

标记过程跟标记/清除算法的一样,证明整理是在标记/清除的基础上将标记的对象按序排好,再将剩下的那块区域全部回收。使用场景:不在乎消耗
在这里插入图片描述

3.2.1.标记/整理算法内存变化图解:

在这里插入图片描述

3.2.2.标记/整理算法缺点:

效率更低:整理引用地址再排队,还是会形成循环引用。

4.总结:

1.分代原因:不同对象的生命周期不同。
如果说同对象的生命周期按照同一种分配策略来划分的话,会把效率降到最低浪费加到最大。
2.复制算法适合朝生夕暮,不在乎内存,因为一进来就死了。
3.Old区适用标记/整理算法原因:进来的对象只是非常少数,回收时整理引用地址再排队的效率相对就不会很低(对象极少)。
4. GC算法本质上本质上是贫民算法。
5.穷:最求效率避免浪费 健壮性

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Fire king

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值