java 如何判断对象可以回收?
垃圾回收机制
-
如何判断对象可以回收?
-
引用计数法:
- 当存在引用时+1,减小引用时 -1;
- 当引用数 = 0时,判断为垃圾;
- 缺:当存在循环引用时,双方引用都是1,就不能判断垃圾;
-
可达性分析算法:
-
根对象:肯定不能当作垃圾进行回收的对象;
-
当一个对象没有直接或间接被根对象引用,则就被当做垃圾。
-
扫描堆中的对象,是否能沿着GC root对象为起点的引用链找到该对象,找不到的为垃圾;
-
根对象【堆中的对象,不是引用变量】:
- 系统核心类【System Class】:String,Object,各种表启动器加载类;
- 操作系统的方类【Native Stack】:Class,
- 线程类【Thread】:启动线程的类,栈帧;
- 加锁的对象【Busy monitor】:Lock类
-
四种引用:
-
强引用:沿着GC root对象链能找到的对象,平时经常使用的方式;
-
软引用:被强引用对象,软引用的对象,当垃圾回收后,内存还不够时,会被回收;
-
弱引用:被强引用对象,弱引用的对象,当发生垃圾回收时,就会被回收;
软、弱引用本身也是对象,当他们的引用的对象,被回收时,会被放入引用队列里【可以做进一步释放,也可以不放】;
//引用队列,可放[自动放入],可不放; ReferenceQueue queue = new ReferenceQueue<>(); SoftReference<byte[]> ref = new SoftReference<>(new byte[_4MB],queue); byte[] data = ref.get(); -
虚引用【配合ByteBuffer使用】:直接内存和ByteBuffer存在虚引用,当ByteBuffer对象被回收的时候,虚引用被放入引用队列;引用队列存在一个线程【Reference Handler】,定时释放引用队列,【调用虚引用相关方法,释放直接内存】;
-
终结器引用:每个对象都会继承finalize()方法,当没有直接引用时,会被放入引用队列【第一次回收时】,被一个Finalizer线程【优先级很低】调用对象的finalize()方法,第二次才能被当作垃圾释放;
虚、终结引用必须配合引用队列使用;
-
-

浙公网安备 33010602011771号