Java对象的强、软、弱、虚引用
概述
Java的方法的对象参数是按值传递的,而不是按引用传递的,即传递的是对象引用的值。对象引用通常是存放在栈中的,而对象引用所引用的对象是存放在堆中的。
在Java中,为了优化内存使用,降低OOM发生的风险,提高垃圾回收的效率,可以在应用程序中根据对象的特点来设置不同类型的对象引用来协助JVM进行垃圾回收。对象引用包括以下类型:除了强引用之外,其他三种引用类型,在GC roots可达的情况下,也可以被回收。
对象引用类型
强引用:默认的对象引用都是强引用,如下:强引用的对象只有在从GC roots不可达时才会被垃圾回收器回收,即使发生了OOM。
// 创建了两个对象,分别是堆中的对象和栈中的对象引用
String str = new String("hello");
软引用:通常用于引用有用但不是必须的对象,如缓存。使用软引用的对象在进行Full GC之后还是没有充足的内存来存放新对象时,可以被回收。即通过回收软引用的对象来释放内存空间,避免发生OOM。如下str就是一个软引用:
SoftReference<String> str = new SoftReference<String>(new String("hello"));
弱引用:弱引用通常用于引用非必需的对象,只要发生GC,不管所引用的对象是否可达,都会被回收。使用弱引用的主要目的是减少GC,而软引用主要是作为OOM的最后一道防线。
WeakReference<String> str = new WeakReference<String>(new String("hello"));
虚引用:虚引用相当于没有引用一样,该虚引用不会影响该对象的生命周期。即如果一个对象只存在一个虚引用,不存在其他引用,则该对象相对于没有任何引用,为不可达对象,任何时候都可以被回收。虚引用存在的作用是:当虚引用所引用的对象被回收时能收到一个系统通知。
由于虚引用的对象每次垃圾回收都会回收,故一个典型应用是监控垃圾回收的发生频次或者进行日志统计。在使用层面,虚引用需要结合一个虚引用队列来使用,目的是当虚引用所引用的对象被回收时,垃圾回收器会将该虚引用填充到该队列中,应用程序如果发现该队列有虚引用填充进来了,则说明所引用的对象被回收了,从而实现了得到系统通知的语义。
如下:
ReferenceQueue<String> queue = new ReferenceQueue<String>();
PhantomReference<String> pstr = new PhantomReference<String>(new String("hello"), queue);
作者:服务端开发
来源:CSDN