首先不要被一些對一些名詞望而生畏,其實都是一些存在即合理的東西。java
引用自己很好理解,引用類型的數據中存放的是實際對象的內存地址,垃圾回收時,就看對象是否存在引用。Java不須要開發人員分配內存和釋放內存,可是能夠經過四種引用類型來處理相關對象生命週期,配合jvm進行垃圾回收。緩存
1.強引用
正常的建立對象,賦值變量都屬於強引用類型,強引用類型在垃圾回收時,不會被回收,內存不足時直接拋出OutOfMemoryError錯誤。jvm
byte[] data = new byte[2*1024*1024]; VM options:-Xms1m -Xmx1m -XX:+PrintGC
好比上面的示例,jvm指定最大堆內存1m,程序要建立一個2m的東西,程序運行時就會直接拋出OOM錯誤。當引用再也不須要關聯對象時,能夠進行null賦值,方便jvm垃圾回收。優化
2.軟引用(SoftReference)
具備軟引用的對象,在內存足夠時不會被回收,在發生OOM以前,纔會被回收。在Java中使用SoftReference聲明一個軟引用,使用get方法返回對象的強引用,當軟引用關聯對象被回收時,get返回null。spa
留着有用,丟了也無妨,這種東東作緩存是合適的,內存不夠用時能夠被垃圾回收器回收,可以有效下降內存溢出風險。但注意軟引用自己是一個強引用,一樣須要清除,能夠經過註冊ReferenceQueue監聽關聯對象已被回收的軟引用自己,進行清除操做。code
byte[] data = new byte[1*1024*1024]; ReferenceQueue<Object> referenceQueue = new ReferenceQueue<>(); SoftReference<byte[]> softReference = new SoftReference<>(data,referenceQueue); data = null; System.out.println("before:"+softReference.get()); try { for (int i = 0; i < 10; i++) { byte[] temp = new byte[3*1024*1024]; System.out.println("processing:"+softReference.get()); } } catch (Throwable t) { System.out.println("after:"+softReference.get()); t.printStackTrace(); } while(referenceQueue.poll()!=null){ System.out.println("self:"+softReference); softReference.clear(); softReference = null; System.out.println("last:"+softReference); } VM options:-Xms5m -Xmx5m -XX:+PrintGC
3.弱引用(WeakReference)
弱引用就更弱了,垃圾回收時直接會被回收掉,Java中使用WeakReference聲明,一次gc就會被幹掉,其他和軟引用相似。對象
byte[] data = new byte[1024*1024]; WeakReference<byte[]> weakReference = new WeakReference<>(data); data = null; System.out.println("before:"+weakReference.get()); System.gc(); System.out.println("after:"+weakReference.get());
結果就是一次gc以後就拿不到關聯對象了,注意這裏是將data置爲null以後,不然data是存在強引用關係的,軟引用亦是如此。生命週期
4.虛引用(PhantomReference)
虛引用和沒有引用同樣,虛引用在使用上必須結合前面提到的ReferenceQueue,能夠經過引用隊列來監聽是否關聯對象將要被回收,能夠在此時機進行處理操做,操做同軟引用。隊列
byte[] data = new byte[1024*1024]; ReferenceQueue<Object> referenceQueue = new ReferenceQueue<>(); PhantomReference<byte[]> phantomReference = new PhantomReference<> (data,referenceQueue); System.out.println(phantomReference.get());
幾種引用本質仍是圍繞在內存回收機制上,瞭解一些知識,有時候可能不會直接用在工做當中,可是能夠在適當的地方或時機去優化部分程序,也能在閱讀一些源碼的時候起到幫助做用。內存