在java中有四种对象引用类型分别为
1. 强引用(StrongReference)
引用所指向的对象在任何时候都不会被系统回收。JVM宁愿抛出OOM异常,也不会回收强引用所指向的对想
2. 软引用(SoftRefernce)
软引用的对象在系统内存不足的时候才会被系统回收掉,可以通过SoftReference类来定义软引用对象,并且可以在定义对象的时候传入ReferenceQueue,在对象被垃圾回收之后会把对应的SoftReference放到ReferenceQueue中
3. 弱引用(WeakReference)
弱引用的对象是会在内存充足的情况下被系统回收掉的,不过回收的优先级很低,如果发现对象只存在于WeakReference中而没有其他的强引用,是很有可能会系统回收掉的,同样在回收掉之后会把对应的WeakReference放到ReferenceQueue中
4. 虚引用(PhantomReference)
虚引用的对象在任何情况下都是会被回收的,经常在调用get方法的情况下返回空,经常结合ReferenceQueue用来了解一个对象是否要被垃圾回收
测试代码如下
默认设置jvm最大堆内存是2M
- 在强引用对象超过最大堆内存的时候,JVM会抛出堆栈溢出
public static void StrongReference() {
System.out.println("this is strong reference");
byte[] bs = new byte[2048 * 300];
System.gc();
}
执行结果如下图
- 在使用软引用对象的时候,如果内存空间足够是不会回收软引用对象的,如果内存空间不够会被回收掉,并且会把SoftReference放到ReferenceQueue中
public static void SoftReference() {
System.out.println("this is soft reference");
Byte[] referenceBytes = new Byte[2048 * 45];
ReferenceQueue referenceQueue = new ReferenceQueue();
WeakReference softReference = new WeakReference<Byte[]>(referenceBytes,referenceQueue);
referenceBytes = null;
System.out.println("soft refernce get reference" + softReference.get());
System.out.println("soft refernce get queue" + referenceQueue.poll());
System.gc();
byte[] bs = new byte[2048 * 250];
System.gc();
System.out.println("soft refernce get reference" + softReference.get());
System.out.println("soft refernce get queue" + referenceQueue.poll());
}
执行结果如下图
3. 在使用弱引用对象的时候,在内存空间充足的情况下也是会回收弱引用对象的,并且会把WeakReference放到ReferenceQueue中,下面这段代码和上面不同的地方就是在调用系统gc方法之前没有定义大对象,但是最终弱引用对象还是被回收掉了
public static void WeakReference() {
System.out.println("this is soft reference");
Byte[] referenceBytes = new Byte[2048 * 10];
ReferenceQueue referenceQueue = new ReferenceQueue();
WeakReference weakReference = new WeakReference<Byte[]>(referenceBytes,referenceQueue);
System.out.println("weak refernce get reference" + weakReference.get());
System.out.println("soft refernce get queue" + referenceQueue.poll());
referenceBytes = null;
System.gc();
//byte[] bs = new byte[2048 * 100];
System.gc();
System.out.println("weak refernce get reference" + weakReference.get());
System.out.println("soft refernce get queue" + referenceQueue.poll());
}
4.虚引用类型在任何情况下都有可能被回收掉
public static void PhantomReference() {
System.out.println("this is phantom reference");
Byte[] referenceBytes = new Byte[2048 * 10];
ReferenceQueue referenceQueue = new ReferenceQueue();
PhantomReference phantomReference = new PhantomReference<Byte[]>(referenceBytes,referenceQueue);
System.out.println("phantom refernce get reference " + phantomReference.get());
System.out.println("phantom refernce get queue " + referenceQueue.poll());
System.gc();
//byte[] bs = new byte[2048 * 100];
System.gc();
System.out.println("phantom refernce get reference " + phantomReference.get());
System.out.println("phantom refernce get queue " + referenceQueue.poll());
}
运行结果如下