1. 对象回收过程?
可达性分析算法: 如果一个对象从 GC Roots 不可达时,则证明此对象不可用。 通过一系列称为GC ROOTS的对象作为起点,从这些起点往下搜索,搜索走过的路径
称为引用链,当一个对象到GC ROOTS 没有任何引用链,我们判定这个对象是可回收的。。
在java 中,可作用GC ROOTS对象的包括:
虚拟机栈(栈针中本地变量表)中引用的对象,
方法区中类静态属性引用的对象,
方法区中常量引用的对象,
本地方法栈中即native 引用的对象。。
具体过程: 在对象不可达时,也并不是非死不可,要真正宣告一个对象死亡,需要进行两次标记过程: 如果一个对象在进行可达性分析后没有与GC ROOTS 的相连接的
引用链,那将会被第一次标记并进行一次筛选: 筛选的目的是判定是否执行finalize方法,当对象没有覆盖finalize 方法,或者finalize 方法已经被虚拟机
调用过,虚拟机认定这两种情况为不必要执行finalize方法。
如果需要执行finalize方法,那么这个对象将会放置在一个F-Queue 队列中,并在稍后建立一个低优先级的线程来执行它。 finalize 方法是对象逃离死亡的
最后机会,在执行finalize 方法时会对F-Queue中的对象进行第二次标记,如果对象在finalize 方法中成功拯救自己(如把this赋值给某个变量,总之就是让
对象出现引用链),则讲该对象移出队列。剩下的对象就只能等待被回收了。
5. synchronized 和 volatile
volatile 修饰的变量对所有线程具有可见性 , 意思是如果一个线程修改了 该变量,另一个线程可以立即获得修改后的新值。但是这个并不是原子性的,在并发
情况下并不是安全的:原因是多个线程在做运算前获取的可能是脏数据,如何 变量++ 操作,先获取变量值,然后+1, 多个线程获取的是脏数据。
volatile 禁止指令重排序优化:指令重排是指java 编译成机器码时会优化语句执行顺序。 如线程A在执行某些操作后把某个变量赋值true, 另一个线程判断true 做一些操作,
指令重排后可能到指线程A 在某些操作 完成之前就把 变量赋值true了。。导致线程B判断true后并不能获取正确的结果(比如我要获取线程A的某些操作结果)