【后端修行之虚拟机】存活判定算法&垃圾回收算法

本文用于记录苦啃《深入理解Java虚拟机:JVM高级特性与最佳实践》后,个人认为有价值的笔记,核心内容均围绕标题展开。既做一个学习的记录,同时也做一个沟通交流,欢迎各位大佬互动~

内存回收关注三个事情:什么样的内存需要回收?什么时间回收?回收方式?

什么样的内存需要回收?

对于区域来讲:java堆以及方法区,因要程序运行时才能知道所需空间,需要内存的大小不确定,因此需要进行内存的回收和管理.

不再使用的东西(堆:对象,方法区:废弃常量\不再使用的类型):

对于对象来讲:那些已经死掉的对象,没用的对象就需要回收管理

存活判定算法

什么样的对象才算死了?

判定对象死亡的算法:引用计数算法/可达性分析算法

引用计数算法

虽然简单,判定效率高.但是难以解决对象循环引用的问题(两个对象相互引用,但是实际外部对象已经不会对他们访问)

可达性分析算法

有一系列符合要求的对象作为GC Roots根节点,然后根据他们的引用关系,搜索其他的相关对象.如果有些对象和这些根节点或与根节点有应用关系的对象没有关系,那么这些对象不可达,说明也不会被引用,使用.

根节点对象包括:①虚拟机栈(局部变量表)reference引用的对象;②类的静态变量引用的对象;③类的常量引用的对象;④本地方法栈中JNI(通常说的Native方法)引用的对象;⑤虚拟机内部引用:基础数据类型的Class对象,常驻异常对象OutOfMemoryError,系统类加载器;⑥所有被同步锁持有的对象;⑦反应Java虚拟机内部情况的JMXBean,JVMTI中注册的回调\本地代码缓存等;⑧有些被引用的对象也可以临时加入

引用关系:强引用/软引用(内存溢出前,会被列入回收范围)/弱引用(只能存活到下一次垃圾收集之前)/虚引用(没办法获得实例,回收后获得系统通知)

对象还没真正死亡,死亡的更进一步,判定了非GC Roots,实际还不会立刻被收集,还会判断对象是否有必要执行finalize()方法,如果确定要执行,对象会被放进一个F-Queue队列,有一个低优先级的线程去执行.如果还能和引用链上的对象建立关联就会被移除集合,否则就是要被真正回收了.

方法区的回收. 涉及两种类型的内容:废弃常量(运行时常量池:字面量/符号引用)不再使用的类型(类型信息)

常量:不被其他内存所引用

类:①该类及其子类在java堆中没有实例;②加载该类的类加载器已被回收③该类对应的Class对象没有在任何地方被引用.同时满足才被允许惊醒回收

垃圾回收算法

分代手机理论:弱分代假说(大多数对象容易死亡),强分代假说(能经过多次的垃圾收集的对象容易存活),跨代引用假说(跨代引用的对象生命周期趋同)

标记-清除算法

两个缺点:①效率不稳定,需要注意逐一标记清楚对象②容易产生大量的内存碎片,当分配大对象的时候容易空间不足触发Full GC

标记-复制算法

半区复制(解决了内存碎片化的问题,但是浪费空间较多)

Eden和S区复制(减少了空间浪费,但是通常适用于新生代,因为需要解决当存活对象内存占用超出S区的问题,这个时候需要老年代进行分配担保)

标记-整理算法

标记和移动都需要STW.  关于移动对象增加程序停顿时间与内存碎片化的矛盾: 从整体吞吐量来看,由于内存的分配和访问比垃圾收集频率更高,因此标记整理算法吞吐量比标记清除算法更高.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值