这应该是一道很常见的面试题,但是有些小伙伴也不一定能很好的说清楚Java对象四种引用方式,这边文章总结Java四种引用方式,希望可以帮到有缘人,哈哈。
强引用StrongReference
这种方式是平时工作中应用最多的一种引用方式。其特点是只要GC Root可达,就不会被回收,及时内存空间不足了,也只会抛出OOM的异常,并不会被回收
。通常的用法就是Objec obj = new Object()
。
如果想中断或者回收强引用对象,可以显式地将引用赋值为null,这样的话JVM就会在合适的时间,进行垃圾回收。
软引用SoftReference
和强引用不同的是,软引用对象在内存中是可有可无的。软引用在GC Root可达且内存充足的时候不会被回收掉,当GC Root可达且内存不足的时候就会被回收掉。
只要软引用对象没有被回收掉,就可以使用。
SoftReference<byte[]> softReference = new SoftReference<>(new byte[1024 * 1024]);
弱引用WeakReference
相信看过ThreadLocal源码的小伙伴对着这种引用一定很熟悉吧。没错,ThreadLocal中的静态内部类ThreadLocalMap里面的entry是一个WeakReference的继承类。
static class Entry extends WeakReference<ThreadLocal<?>> {
/** The value associated with this ThreadLocal. */
Object value;
Entry(ThreadLocal<?> k, Object v) {
super(k);
value = v;
}
}
只要发生了GC,弱引用对象就会被回收掉。
虚引用PhantomReference
虚引用的设计和上面三种引用有些不同,它并不影响GC,而是为了在对象被GC时,能够收到一个系统通知。
那它是怎么被通知的呢?虚引用必须要配合ReferenceQueue,当GC准备回收一个对象,如果发现它还有虚引用,就会在回收之前,把这个虚引用加入到与之关联的ReferenceQueue中。
Object obj = new Object();
ReferenceQueue queue = new ReferenceQueue();
PhantomReference<Object> phantomObj = new PhantomReference<Object>(obj , queue);
obj = null; //去除强引用
总结
一般来说强引用是平时开发中应用最多的,虚引用基本不怎么用。而软引用和弱引用的区别就是:软引用在内存不足的时候进行回收,弱引用只要进行GC就会被直接回收掉。