这个确定对象是不是还有用 ,可以不可以扔掉 的算法
不止是Java在用, 主流的商用语言都是这个
基本思路:
以一些 GC Roots 作为跟, 向下搜索,
走过的路径叫引用链
, 没走到的,就是不可达
不可达的 就是 没用了的
Java里面可作为GC Roots的
虚拟机栈/本地方法栈 中引用的对象
就是个线程在运行的方法里面用到的对象
方法区中 类静态属性/常量 引用的对象
就是是属于类的static field 和final static field
被作为锁的对象
反应JVM内部情况的对象
其他不回收的区域,可能对本区域引用的对象
4种引用
强
软
空间不足一段时间后, 才会迫不得已回收它们
适合做缓存
弱
活不过下次回收,
这个在ThreadLocal 里面用到了,
既可以通过这个引用拿到threadLocal 对象,
如果其他强引用(来自各个线程的引用)不在了, 定义这个static threadLocal 的class里面对 threadLocal 的引用 不会阻止其被回收
虚
作用是 回收时可以得到通知
finalize()
这个方法没啥用 ,不要用
某对象 如果 没在引用链
上,就是是死的
会看它是否有覆盖finalize
方法,
如果有写finalize
方法,并且没执行过
就会放到一个F-Queue队列里面,
有一个优先级很低的线程, 过一会儿来运行, 但是不保证给你运行完, 如果花费太大就算了
如果在
finalize
里面写的 xxx=this 再给建立一个引用 把他救活 是可以的
但是只能这么做一次, 下次回收 发现又没有引用的话
这个对象finalize
已经被执行过了, 是不会被再次执行的
二次标记:
指的是 finalize
里面是可以救 这个对象的
通过再次建立引用, 把这个对象移出 待回收 的集合
方法区 的回收
又叫类卸载
虚拟机规范里面, 没有要求 一定要对 方法区进行回收, 确实也有收集器(11的ZGC)没有类卸载
类卸载, 条件苛刻,收效甚微
但是,现在动态代理 CGLib字节码框架,动态生成类,OSGI频繁自定义类加载器, JVM比较小 可以类卸载
以下条件是 类不再被需要,可以被卸载的 必要条件(非充分):
- 没实例了
- 类加载器 没了
- 对应的Class对象 没了
以上↑ 是必要条件
实际上, 什么样的情况运行类卸载 , 可通过参数自己控制
可以查看 类加载 类卸载信息
网友评论