来自颜群老师的JVM课程
引用级别
根据引用的强弱关系:强>软>弱>虚
各种引用的出处
- 强引用:new
- 软、弱、虚 + 最终引用:java.lang.ref.Reference
问题:如果一个对象存在着指向它的引用,是否该对象不会被GC回收?
不一定。即便是:Object obj = new Object(); 这样的强引用,也会存在一定的局限性
强引用
Object obj = new Object();
约定:引用==obj,引用对象 == new Object()
问题:强引用对象什么时候失效?
- 生命周期结束(作用域失效)
当方法执行完毕后,强引用指向的“引用对象”这里是new Object()失效,等待GC回收 - 置为null
obj = null;
此时,没有任何引用指向new Object();,等待GC回收
小结:
除了以上两个情况以外,任何时候GC都不会回收强引用对象。这也是为什么GC宁可撑爆堆空间也不释放强引用对象的原因,最终会造成OOM
软引用
根据JVM内存情况:
如果内存充足,GC不会随便的回收软引用对象,
如果内存不足,GC就会主动回收软引用对象
软引用的使用方法:
如果softReference对象所指向的引用对象为null,则说明软引用对象被GC回收。
注意:出现的问题
线程代码中如果没有输出语句或是线程休眠语句,则会直接抛出OOM,但是却不显示软引用回收。为什么呢?
原因是线程代码中的死循环,导致softReference.get()一直被调用,没有空闲将本工作内存的数据刷新到主内存,导致main线程无法获得输出信息。
解决方法:
- 在if语句之前进行线程休眠,让工作线程有空闲往主内存中刷新数据。
- 凡是能制造一些空隙的时间都可以给主内存做同步。
弱引用
只要内存爆了,无论什么对象都会被GC回收
弱引用使用: