連引用都答不上,憑什麼說你是Java服務端開發

2021-01-14 飯談IT

【乾貨點】看完該篇文章,就基本可以解答面試熱點【談談對Java中幾種引用的理解】了。

最近就說到了一個面試題

談談對Java中幾種引用的理解。

因此打算以該面試題為例子,寫篇文章說說在Java中引用是什麼以及怎麼用。【劃重點:給你三秒鐘時間思考,如果是你,該如何回答面試官的這個問題呢】

引用是什麼

【劃重點】在Java中引用包括:

FinalReference 強引用SoftReference 軟引用WeakReference 弱引用PhantomReference 虛引用那麼為什麼會提供這四種引用呢,主要原因有:

方便Jvm進行垃圾回收方便開發人員使用,開發人員可以靈活的決定某些對象的生命周期日常開發如何使用

學以致用,那麼這幾個引用在日常中我們如何進行使用呢?接下來我會給出相關demo!!!

FinalReference 強引用

類似於 Object o = new Object() 這類的引用,創建一個對象後,該引用會被保存在JVM棧中,而且只要強引用存在,垃圾回收器就不會回收掉被引用的對象。

日常使用

強引用的例子比比皆是,因為在日常開發中我們是會經常去new一個對象的,而該new出來的對象便是強引用的,也就是說只要該引用存在,垃圾回收器就不會回收掉。【劃重點:JVM怎麼知道引用在不在?】

SoftReference 軟引用

軟引用關聯的對象,在內存不夠的情況下,會把這些軟引用關聯的對象列入垃圾回收範圍中,然後進行回收,也就是說軟引用並非是完全安全的,在內存不夠的情況下是會被垃圾回收器回收掉的。

給出demo

通過注釋便可以知道,我這裡實例化了多個大對象,然後放入softReferences數組中,之後便遍歷列印出其中的對象的命名,列印結果如下

可以通過結果看出,前面四個對象因為內存不夠而被垃圾回收器回收了。

日常使用

在我司的項目中,部分是使用軟引用來保存從資料庫中取出的數據,具體是做了一個中間層的封裝,該中間層的作用就是在get出數據的時候會去判斷數據是否為null,如果是為null再次從資料庫讀取,讀取後再放入軟引用的集合中,這樣的做法是可以避免內存溢出。

WeakReference 弱引用

弱引用比軟引用更弱,被弱引用關聯的對象只能存活到發生下一次垃圾回收之前,也就是說當發生GC時,無論當前內存是否足夠,都會被回收掉。

給出demo

代碼很簡短,就是先構建一個弱引用對象,然後在gc前先列印出來證明它存在過,之後手動調用gc,再次列印,可以看出已經沒了。運行結果如下

PhantomReference 虛引用

虛引用和上面不同的地方在於,一個對象是否有虛引用的存在,完全不會對其生存時間構成如何影響,並且也無法通過虛引用來獲取一個對象的實例,也就是說跟沒有引用與之關聯一樣,在任何時候都可能被垃圾回收器回收。

那麼這樣就很容易產生疑問了,虛引用的作用又是什麼呢?

作用就是能在這個對象被收集器回收時收到一個系統通知,實現追蹤垃圾收集器的回收動作,比如在對象被回收的時候,會調用該對象的finalize方法。

在給出相關demo前,要先介紹一個

ReferenceQueue 引用隊列

ReferenceQueue 引用其實也可以歸納為引用中的一員,可以和上述三種引用類型組合使用【軟引用、弱引用、虛引用】。

那麼它有何作呢?

在創建Reference時,手動將Queue註冊到Reference中,而當該Reference所引用的對象被垃圾收集器回收時,JVM會將該Reference放到該隊列中,而我們便可以對該隊列做些其他業務,相當於一種通知機制。

給出demo

可以從demo中看出隊列的用法,運行列印結果如下

我們可以從結果中看到先是從引用中get出來的對象為null,證明上面說的無法通過虛引用來獲取一個對象的實例,並且在回收後會被放入隊列中。

和Reference相關的概念

首先為了方便JVM進行管理,Reference是有狀態的,可以分為以下四種狀態

active 一般來說內存一開始被分配的狀態,而當被引用的對象的可達性發生變化後gc就會將引用放入pending隊列並將其狀態改為pending狀態。pending 指的是準備要被放進pending隊列的對象。enqueue 指的是對象的內存已經被回收了。inactive 這是最終的狀態,不能再變為其它狀態。JVM怎麼知道引用在不在

關於JVM怎麼知道引用在不在,這就涉及到了JVM的可達性分析算法了JVM的可達性分析算法的簡單思路就是通過一系列GC Roots作為出發點,向下搜索,搜索所走過的路徑稱為引用鏈,當一個對象到GC Roots沒有任何引用鏈,即表明從GC Roots到這個對象不可達時,證明此對象不可用,可被回收。如下圖所示

對象4、5、6都是可被回收的。那麼問題來了,哪些對象可以作為GC Roots呢?這裡給出幾個,如下

虛擬機棧中引用的對象方法區中類靜態屬性引用的對象方法區中常量引用的對象本地方法棧JNI引用的對象具體的想要深入研究的可以自行百度&谷歌,或者等我後面深入分析。

最後的最後

該篇文章基本解答了【談談對Java中幾種引用的理解】,如果想要更深入的研究,就要從源碼入手了解了。下次遇見這種面試題,基本上就不慌了,因為實際上只要認真看完該篇文章並且記住幾個關鍵的地方,基本上就不會被面試官問倒了,並且該篇文章後面也解答了【JVM怎麼知道引用在不在】和【哪些對象可以作為GC Roots】的問題。

相關焦點

  • SAP ABAP和Java裡的弱引用(WeakReference)和軟引用(SoftReference)
    而其他三種排列組合下,lcl_person都逃脫了被垃圾回收器回收的命運:Java裡也有對應CL_ABAP_WEAK_REFERENCE的弱引用實現:java.lang.ref.WeakReference.
  • Javaweb開發學習路線及Java三大框架分享
    Java web開發是什麼?Java web開發,是用Java技術來解決相關web網際網路領域的技術總和。web包括:web伺服器和web客戶端兩部分。Java在客戶端的應用有java applet,不過使用得很少,Java在伺服器端的應用非常的豐富,比如Servlet,JSP和第三方框架等等。Java技術對Web領域的發展注入了強大的動力。
  • 為什麼要學習Java開發 學Java有什麼優勢?
    Java生態系統的完善性主要體現在以下幾個方面:4、Java擁有世界上數量最多的程式設計師填寫下面表單即可預約申請免費試聽java課程!害怕學不會?助教全程陪讀,隨時解惑!擔心就業?一地學習,可全國推薦就業!你說他們是農民也好,但數量放在那裡,最明顯的效果就是公司招人的時候會比較容易地招到Java程式設計師。
  • Java基礎面試題簡單總結
    Java內部類與C++嵌套類最大的不同就在於是否有指向外部的引用上。Collections是針對集合類的一個幫助類,他提供一系列靜態方法實現對各種集合的搜索、排序、線程安全化等操作6、什麼時候用assert答:assertion(斷言)在軟體開發中是一種常用的調試方式,很多開發語言中都支持這種機制。
  • 學習java開發可以做什麼工作
    在現實生活中,大多數人選擇java開發這個行業都是看好java的發展前景,那麼java學好了之後可以做些什麼呢? 1、企業級應用開發 企業級應用開發大可以做全國聯網的系統,小到中小企業的應用解決方案。
  • 乾貨|Java 線上故障排查完整套路!牛掰!
    如果說一切都正常,才需要通過調整Xmx的值來擴大內存。注意這邊的超時大部分是指邏輯上的超時。soa 的超時指的也是讀超時。讀寫超時一般都只針對客戶端設置。連接超時。connectionTimeout,客戶端通常指與服務端建立連接的最大時間。服務端這邊 connectionTimeout 就有些五花八門了,Jetty 中表示空閒連接清理時間,Tomcat 則表示連接維持的最大時間。
  • NIO框架入門(二):服務端基於MINA2的UDP雙向通信Demo演示
    前言 NIO框架的流行,使得開發大並發、高性能的網際網路服務端成為可能。 Demo的代碼邏輯 言歸正傳,本文要演示的Demo包含兩部分,Java UDP客戶端和MINA2 UDP服務端,客戶端將每隔3秒向服務端發送一條消息,而服務端在收到消息後馬上回復一條消息給客戶端。也就是說,服務端和客戶端都要實現消息的發送和接收,這也就實現了雙向通信。
  • 開發崗位這麼多,為什麼選Java?你學Java了嗎-開課吧
    TIOBE編程排行榜根據全球工程師、課程和搜尋引擎數量為指數得出,在一定程度上反映了程式語言的發展趨勢。程式語言排行榜目前很多軟體都是用Java寫的,新出的系統和函數庫為了市場,也會儘量和Java兼容或者提供Java的接口。
  • 面試官:連Serializable都不知道是什麼,你這5年都幹些什麼了?
    張工是一名java程式設計師,工作5年了,一直從事java開發。最近到某網際網路公司面試,做了筆試題後,有一道筆試題是這樣子的:Serializable有什麼作用,張工沒有作答,面談時面試官又問了,張工回答不出個所以然。面試官:你都工作五年了,連序列化都不知道,你這5年都幹些什麼了?張工一臉的無助,不過確實不應該,類似Serializable序列化這樣的知識點,平時應該不會少用。
  • python開發web服務 bottle框架
    開發功能不是特別複雜的web服務,可以考慮使用bottle框架。原因:一、Python開發效率高呀!不信你比比同樣的功能Python幾行可以搞定?換java試試?換C++試試?作為這幾種語言都使用過的我來說,用過java就儘量不用C++,用過Python就儘量不用java,真的不堪回首。
  • JAVA8——JAVA成長之路
    現在幾乎可以為任何東西添加註解:局部變量、泛型類、父類與接口的實現,就連方法的異常也能添加註解。Stream API、Lambda表達式與方法引用在接口默認方法與靜態方法的配合下是Java 8對現代軟體開發範式的回應。更多詳情請參考官方文檔。
  • java-web新手開發快速入門
    java-web開發快速入門,本文對於java-web開發的要點進行了重點分析,可以給新手們提供很好的參考作用。四、web應用的組織結構:五、配置虛擬主機:(1).配置虛擬主機,只需要在server.xml配置文件中,添加一個<Host name="" appBase=""/>節點(2).配置好的虛擬主機要想被外界訪問到,必須在dns伺服器上註冊(購買域名)或者在windows系統中的hosts文件進行註冊。
  • Java開發一般需要學幾個月?學費多少?來看看西安匯傑怎麼說
    但需要特別注意一點就是,學習周期少於4個月的課程是不是說明學習的知識點不多?課程周期大於5個月的是不是說明學的更多?其實,不以為然。少於4個月學習周期的機構,一般會把課程進度放的比較快,也就是說學習的知識點不一定深入及紮實。
  • Java高級開發必會的50個性能優化的細節(珍藏版)
    在大多數情況下,你可以在創建 StringBuffer的時候指定大小,這樣就避免了在容量不夠的時候自動增長,以提高性能。●19. 儘量早釋放無用對象的引用大部分時,方法局部引用變量所引用的對象會隨著方法結束而變成垃圾,因此,大部分時候程序無需將局部,引用變量顯式設為null。
  • Linux系統下Java通過shell腳本監控重啟服務
    思路 java程序獲取linux進程信息可以通過shell腳本獲取進程信息、通過讀取proc文件系統獲取進程信息。 但是為了系統的安全性、方便維護等角度出發,更多的是java通過shell獲取和linux交互能力。
  • 給Java新手的一些建議——Java知識點歸納(Java基礎部分)
    JVM作為java運行的基礎,很難相信對於JVM一點都不了解的人可以把java語言吃得很透。我在面試有超過3年Java經驗的開發者的時候, JVM幾乎就是一個必問的問題了。當然JVM不是唯一決定技術能力好壞的面試問題,但是可以佐證java開發能力的高低。
  • JAVA反序列化 - commons-collections - 1
    No.2前言這是個人學習java反序列化的第一篇利用鏈的文章,就好像P牛說的不知道為什麼網上講到java反序列化學習,上來就是cc鏈,你知道這個鏈它有多複雜麼.jpg。萌新也是理所當然的踩了這個坑,然後…..在一路質疑自己智商和"我不服"的情況下趟了過去。
  • Java面向對象的基本概念,一定要牢記
    面向過程和面向對象的區別舉例:大象裝進冰箱面向過程思考: 打開冰箱 —> 存儲大象 —> 關上冰箱面向對象思考: 冰箱:供電、冰箱門、冷凍、存儲大象:大大的耳朵、短短的腿、會吃會跑又會叫 對於面向過程思想OPP,強調的是過程(動作)主要關注「怎麼做」。
  • 用eclipse3.62開發第一個java程序
    3.用eclipse3.62開發第一個java程序:使用eclipse之前們需要先配置一下jdk。window/preference/java/installed JREs,詳細請見視頻。我們書中(spring架構,ajax, android)都用eclipse3.62,所以我們還要說明在eclipse中運行helloworld! 在eclipse3.62中:馬克- to-win:馬克 java社區:防盜版實名手機尾號: 73203。
  • java中為什麼不推薦使用finalize,知道原因後相信你也不會用了
    java提供了一個finalize方法,可以幫助我們進行資源釋放,類似於C++中的析構函數。但是目前普遍的認識是不要使用,為什麼呢?就是因為對java虛擬機的垃圾回收有影響。這篇文章對其進行一個說明。一、為什麼有影響我們都知道一個對象如果沒有了任何引用,java虛擬機就認為這個對象沒什麼用了,就會對其進行垃圾回收,但是如果這個對象包含了finalize函數,性質就不一樣了。怎麼不一樣了呢?