Java的引用类型有哪4种
- 强引用
- 软引用
- 弱引用
- 虚引用
每个引用的有什么不同
强引用:像我们平时用new关键字创建出来的对象引用对象就是属于强引用,对于强引用类型的对象,虚拟机宁愿抛出OOM异常,也不会去回收这个对象,所以强引用可能会造成内存泄漏。
软引用:软引用是通过SoftReference类实现的。如果一个对象只有软引用,一旦内存不足时,这个对象就会被自动回收,反之则不会。
弱引用:弱引用是通过WeakReference类实现的。如果一个对象只有弱引用,不管内存足不足够,这个对象一定会在垃圾回收过程时被回收。
虚引用:虚引用是通过PhantomReference类实现的。虚引用是所有引用类型里最弱的一个,几乎就是没有引用一样,随时都可能被回收。虚引用必须和引用队列联合使用,主要用来跟踪对象的垃圾回收过程。
用代码测试软引用和弱引用效果
软引用测试代码:
public class TestMain {
public static void main(String[] args) throws Exception {
//强引用
String string = new String("test");
//软引用
SoftReference<String> softReference = new SoftReference<>(string);
System.out.println("垃圾回收前强引用值:" + string);
System.out.println("垃圾回收前软引用值:" + softReference.get());
//设为null,去掉强引用
string = null;
//垃圾回收
System.gc();
System.out.println("垃圾回收后强引用值:" + string);
System.out.println("垃圾回收后软引用值:" + softReference.get());
}
}
运行结果如下:
可以看到在内存足够的情况下,垃圾回收后软引用值依旧为test。
修改最大堆内存为2M:
修改软引用测试代码:
public class TestMain {
public static void main(String[] args) throws Exception {
//强引用
String string = new String("test");
//加个软引用,这是就有两个引用指向String对象
SoftReference<String> softReference = new SoftReference<>(string);
System.out.println("垃圾回收前强引用值:" + string);
System.out.println("垃圾回收前软引用值:" + softReference.get());
//设为null,去掉强引用
string = null;
//垃圾回收
System.gc();
//强行创建一个字节数组占据一大堆内存
byte[] bytes = new byte[524200];
//垃圾回收
System.gc();
System.out.println("垃圾回收后强引用值:" + string);
System.out.println("垃圾回收后软引用值:" + softReference.get());
}
}
运行结果如下:
可以发现在大部分的内存被占据后,内存空间不足的情况下,软引用的对象就会被回收。
弱引用测试代码:
public class TestMain {
public static void main(String[] args) throws Exception {
//强引用
String string = new String("test");
//加个弱引用,这是就有两个引用指向String对象
WeakReference<String> weakReference = new WeakReference<>(string);
System.out.println("垃圾回收前强引用值:" + string);
System.out.println("垃圾回收前弱引用值:" + weakReference.get());
//设为null,去掉强引用
string = null;
//垃圾回收
System.gc();
System.out.println("垃圾回收后强引用值:" + string);
System.out.println("垃圾回收后弱引用值:" + weakReference.get());
}
}
运行结果如下:
可以发现只要进行了垃圾回收,弱引用对象就会被回收。
总结
了解了4种引用类型的特点,我们可以发现软引用和弱引用可以在一定程度上避免OOM结果,同时灵活使用软引用和弱引用可以提高内存的使用效率。