@mapperscan mapper还是无法引用_高能来了!Java的四大引用
文章很長文末有福利
Java中的四大引用
1. 強引用(StrongReference)
我們平常使用new操作符來創建的對象就是強引用對象,只要有一個引用存在,垃圾回收器永遠不可能回收具有強引用的對象。
Object obj=new Object();注意:
強引用的對象并不是永遠不會被回收,需要把obj值為null,或者超出對象的生命周期之后,GC就有機會去回收它,具體什么時候回收要看GC。還有,這里的StrongReference只是一個對強引用的稱呼,在java中并沒有對應的實體類。
2. 軟引用(SoftReference)
軟引用是用來描述一些還有用但并非必須的對象。當內存充足時,垃圾回收器不會清理具有軟引用的對象,只有當內存不足時垃圾回收器才會去清理這些對象,如果清理完軟引用的對象后內存還是不足才會拋出異常。軟引用在java中也是一個對象,對應的實體類是SoftReference案例:
這個案例我們事先把最大堆內存改為了24M
-Xmx24M/** * 軟引用demo * SoftReference * 1.當內存不足的時,JVM就會把軟引用對象進行回收 * 2.如果回收后還是沒有足夠的內存,才會拋出內存溢出異常 */public static void main(String[] args) throws InterruptedException { SoftReference s=new SoftReference<>(new byte[1024*1024*10]);//10m System.out.println(s.get()); System.gc();//啟動GC Thread.sleep(500); System.out.println(s.get()); //再創建一個數組,堆中存不下的時候,垃圾回收器工作 //先回收一次,如果第一次回收后內存還是不夠 //則再清理第二次,這一次會把軟引用對象清除 byte[] b=new byte[1024*1024*15];//15m System.out.println(s.get());//null}控制臺打印結果
[B@2a139a55[B@2a139a55null此外,還可以通過以下JVM參數來打印GC日志
-XX:+PrintGC //打印簡單的GC日志-XX:+PrintGCDetails //打印詳細的GC日志通過控制臺的打印結果我們得出結論:內存充足的情況下,具有軟引用的對象不會被垃圾回收器回收,當再次創建了新的對象,結果導致堆內存不足時就會啟動第一次GC,這一次不會回收軟引用關聯的對象,但是當第一次清理之后發現內存還是不夠,則會再啟動第二次GC,這一次GC才會清理掉軟引用關聯的對象。
由于,在JAVA中軟引用也是一個類,我們需要軟引用需要創建軟引用類實例,我們在上面案例中,變量s的引用指向的是new SoftReference()這個實例對象,屬于強引用關系,而在這個實例對象的里面又去引用了我們new出來的byte數組實例,這個引用是軟引用關系。
SoftReference s=new SoftReference<>(new byte[1024*1024*10]);關系圖如下:
軟引用非常適合用在緩存中,假如用戶訪問的系統中需要加載很多圖片,內存夠用的時候可以緩存很多圖片,假如內存不夠用了,再把圖片先回收掉也無妨,下次需要的時候再加載一次即可。
3. 弱引用(WeakReference)
無論內存夠不夠,只要垃圾回收器啟動,弱引用關聯的對象肯定被回收。
弱引用對象的實體類是WeakReference。
案例:
/** * 弱引用demo * WeakReference * 不管內存夠不夠,都會進行回收 */public static void main(String[] args) { WeakReference w=new WeakReference(new Object()); System.out.println(w.get()); System.gc(); System.out.println(w.get());}控制臺打印結果
java.lang.Object@2a139a55null可以看出,弱引用關聯的對象只能存活到下一次啟動GC之前。
弱引用可以用來解決內存泄露的問題,比如:ThreadLocal中的key就使用到了弱引用來防止內存泄露,ThreadLocal的相關文章在末尾。
關系圖如下:
4. 虛引用(PhantomReference)
虛引用,又稱作幻象引用,如果一個對象具有虛引用,那么它和沒有任何引用一樣,被虛引用關聯的對象引用通過get方法獲取到的永遠為null,也就是說這種對象在任何時候都有可能被垃圾回收器回收,通過這種方式關聯的對象也無法調用對象中的方法。虛引用主要是用來管理堆外內存的,通過ReferenceQueue這個類實現,當一個對象被回收的時候,會向這個引用隊列里面添加相關數據,給一個通知。
案例一:
Object obj=new Object(); PhantomReference objRef=new PhantomReference(obj,null); System.out.println("獲取虛引用所指向的對象"+objRef.get()); System.out.println(objRef.get().equals(obj));//嘗試調用對象中的方法控制臺打印結果
虛引用配合ReferenceQueue類,可以用來管理堆外內存,如果虛引用對象被回收后,會向引用隊列里面發送一個通知,可以參考以下demo便于理解。
案例二:
/** * 虛引用 * 管理堆外內存 */public class Test_PhantomReference {//引用隊列private static final ReferenceQueue QUEUE=new ReferenceQueue<>();public static void main(String[] args) { //當虛引用對象被回收時,會把一個信息填入到引用隊列中 PhantomReference p=new PhantomReference(new Object(),QUEUE); System.out.println("第一次獲取虛引用指示的對象"+p.get());//null System.out.println("第一次獲取虛引用的地址值"+p); List list=new ArrayList<>(); new Thread(()->{ boolean flag=true; try { while(flag) { //不斷去new新的對象,內存不足時GC就會啟動 list.add(new byte[1024*1024]); } } catch (Exception e) { e.printStackTrace(); }finally { flag=false; System.out.println("第二次獲取虛引用指示的對象"+p.get()); } }).start(); /* 再開啟一個線程,做一個監控 * 當虛引用被回收時,會發送一個通知 * 如果引用隊列QUEUE中不再是null * 證明虛引用已經被回收 */ new Thread(()->{ boolean flag=true; while(flag) { Reference extends Object> poll = QUEUE.poll(); if(poll!=null) { flag=false; System.out.println("虛引用對象"+poll+"被回收了"); } } }).start();}}虛引用可以用來管理堆外內存,以上案例中我們結合了一個Queue來進行測試,開啟一個線程來進行監控,假如虛引用對象被回收那么通過poll方法就可以得知
各位朋友如果喜歡的話可以關注我,轉發或者私信,為各位跟各位朋友相識準備了很多資料想分享大家
也可以加群 978652943
總結
以上是生活随笔為你收集整理的@mapperscan mapper还是无法引用_高能来了!Java的四大引用的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: wpf 放大缩小界面_调整电脑屏幕文本文
- 下一篇: dpi重启后会恢复_Linux 系统的备