java 中存在四大引用:强引用, 软引用, 弱引用, 虚引用。 下面来分别介绍一下这些引用:
一 强引用
在我们做java开发过程中,这种引用是最常见的,大部分的引用都是强引用。强引用是在引用没有结束时,引用对象是不会被回收的,当内存不够的时候会直接抛出内存溢出异常。我们常写的代码Object obj = new Object();
这类代码所new出来的对象都属于强引用。代码示例如下:
//-Xms80m -Xmx80m -XX:+PrintGC
//设置最小和最大堆内存大小都为80M, 并且设置如果出现垃圾回收打印垃圾回收信息
public class StrongRefenceTest {
public static void main(String[] args) throws InterruptedException{
byte[] b = new byte[1024*1024*30];
System.out.println("第一次手动执行垃圾回收之前");
System.gc();
byte[] c = new byte[1024*1024*50];
}
}
//执行结果如下:
第一次手动执行垃圾回收之前
[GC (System.gc()) 31979K->31392K(78848K), 0.0007511 secs]
[Full GC (System.gc()) 31392K->31234K(78848K), 0.0036798 secs]
[GC (Allocation Failure) 31234K->31234K(78848K), 0.0007429 secs]
[GC (Allocation Failure) 31234K->31234K(78848K), 0.0003486 secs]
[Full GC (Allocation Failure) 31234K->31234K(78848K), 0.0015475 secs]
[GC (Allocation Failure) 31234K->31234K(78848K), 0.0003387 secs]
[Full GC (Allocation Failure) 31234K->31222K(78848K), 0.0034335 secs]
Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
at zd.reference.StrongRefenceTest.main(StrongRefenceTest.java:12)
从上述的代码示例中我们可以看到在初始化b这个字节数字的时候,堆内存已经占用了31979KB这么大的内存空间了。通过执行System.gc()这个方法进行第一次垃圾回收的时候触发了一次mojor gc,这次mojor gc将堆内存由31979K减小到了31392K, 整个堆内存大小为78848K,第一次mojorGC的时间是0.0007511秒。紧接着产生了一次full gc,回收堆内存中的老年代对象,从执行结果中显示,这次full gc将内存31392K回收到了31234K。后面的几次垃圾回收这里我就不做过多的赘述了。最下面出现了一个OutOfMemoryError异常,表明了在强引用的引用结束之前,不能进行垃圾回收,在内存不够的时候,直接抛出异常。
二 软引用
软引用,软引用一般作用于比较相对不太重要的对象的引用,比如说一个网站的页面的图片等。软引用的对象的特点就是当内存不够的时候,触发GC会将内存中软引用的对象回收掉。如果内存足够便不会回收。软引用的代码示例如下:
import java.lang.ref.SoftReference;
//-Xms80m -Xmx80m -XX:+PrintGC
//设置最小和最大堆内存大小都为80M, 并且设置如果出现垃圾回收打印垃圾回收信息
public class SoftReferenceT