1.如何判断对象已死?(判断算法)

(1)引用计数算法

缺点:无法解决循环依赖

(2)可达性分析算法

标记不可达后并不一定死亡,之前还有一次判断finalize()是否有必要执行的自救机会。
①覆盖了finalize②未执行过finalize
保证这两点后对象将被加入一个等待执行finalize的队列,但并不一定保证自救成功,也就是不一定真的会执行finalize

2.GCRoots包含哪些对象?

	1.虚拟机栈中的引用对象(参数,局部变量,临时变量)
	2.方法区中静态属性对象(static)
	3.方法区中常量对象(finall)
	4.本地方法引用对象
	5.虚拟机内部引用(如基本数据类型对象,异常对象,类加载器)
	6.同步锁持有对象(synchronized)
	7.反应虚拟机内部情况的JMXBean、JVMT1中注册的回调、本地代码缓存等

3.方法区回收内容?

(1)废弃常量

不再被使用的字面量等常量池中的内容

(2)不再使用的类型(如何判断?)

在这里插入图片描述

3.分带假说?

1.弱分代假说:绝大多数对象是朝生夕灭的
2.强分代假说:越是熬过多次垃圾收集的对象越难以消亡
3.跨代引用假说:存在相互引用关系的两个对象应该是倾向于同生共死的

4.垃圾收集算法?

(1)标记清除算法

效率低,碎片化内存

(2)标记复制算法

空间浪费高,无碎片
解决:提出“Appel”式回收–新生代分为Eden、From Survivor、To Survivor 8:1:1。前两区可分配内存。eden快满时发生minor gc->将eden存活对象放到ts,fs中存活对象,一部分放入老年代,一部分放入ts->清空eden,fs->交换ts、fs

(3)标记整理算法–更适合老年代

无需标记复制一样的“分配担保(ts不足容纳)”,但是需要暂停用户线程

5.Hotspot算法细节?

(1)根节点枚举

由于根节点枚举过程必须stop the world,为保证效率,使用OopMap(普通对象指针图)来保证准确式垃圾收集,类加载完成时和即时编译过程中,将记录下哪些位置是引用。详见深入理解java虚拟机第3版,123页

(2)安全点(抢先式中断、主动式中断)

为每条指令都生成oopmap过于浪费空间,所以只在特定位置(安全点)记录oopmap并且只在这些位置才能开始垃圾收集。安全点选取标准是:是否具有让程序长时间执行的特征,例如方法调用、循环跳转、异常跳转。

在这里插入图片描述

主动式中断,采用  内存保护陷阱  方式保证轮询操作高效性;何为内存保护陷阱?如用一条test指令检测一个地址是否为真,如果为真产生异常,转去异常处理程序处理。

(3)安全区域

安全点保证程序执行时进入垃圾收集状态,安全区域解决不执行时进入。
①安全区域保证这片代码中引用关系不发生变化
②安全区域内的线程不会被收集,线程离开时检查虚拟机是否完成根节点枚举,未完成则等待

(4)记忆集与卡表

记忆集用于记录非收集区指向收集区的指针结合,卡表是记忆集定义了记录精度(卡)、与堆内存映射关系的实现。卡表可用字节数组实现。
采用写屏障更新卡表,在每个引用对象赋值操作时产生环形通知,但是会导致伪共享问题。

(5)并发时可达性分析-三色标记

1.浮动垃圾问题
2.对象消失问题
  产生条件:①赋值器插入了从黑色到白色的新引用
       	  ②赋值器删除了全部从灰色到白色的引用
  解决:①增量更新:破坏条件①,并发扫描结束后,以记录过的有变动的黑色对象为根再扫描一遍
       ②原始快照:破坏条件②,并发扫描结束后,以记录过的变化之前的灰色对象为根再扫描一遍
Logo

华为开发者空间,是为全球开发者打造的专属开发空间,汇聚了华为优质开发资源及工具,致力于让每一位开发者拥有一台云主机,基于华为根生态开发、创新。

更多推荐