初學者或初級程序員在面試時如果能證明自己具有分析內存用量和內存調優的能力,這相當有利,因為這是針對5年左右相關經驗的高級程序員的要求。而對於高級程序員來說,如果能在面試時讓面試官感覺你確實做過內存調優的工作,那麼面試官很有可能不問Java Core部分的其它問題了,畢竟虛擬機調優是Java Core部分非常資深的知識點。
在Java對象裡,有強弱軟虛四種引用,它們都和垃圾回收流程密切相關,在項目裡,我們可以通過合理地使用不同類型的引用來優化代碼的內存使用性能。
指向通過new得到的內存空間的引用叫強引用。比如有String a = newString(“123”);其中的a就是一個強引用,它指向了一塊內容是123的堆空間。
平時我們用的最多的引用就是強引用,以至於很多人還不知道有其他類型引用的存在,下面我們來說下弱軟虛這三種平時不常見(但在關鍵時刻不可替代)的用途。
一、軟引用和弱引用的用法
軟引用(SoftReference)的含義是,如果一個對象只具有軟引用,而當前虛擬機堆內存空間足夠,那麼垃圾回收器就不會回收它,反之就會回收這些軟引用指向的對象。
弱引用(WeakReference)與軟引用的區別在於,垃圾回收器一旦發現某塊內存上只有弱引用(一定請注意只有弱引用,沒強引用),不管當前內存空間是否足夠,那麼都會回收這塊內存。
通過下面的ReferenceDemo.java,我們來看下軟引用和弱引用的用法,並對比一下它們的差別。
在第7行裡,我們定義了SoftReference
接下來我們通過下表來觀察下具體針對內存空間的操作:
二、軟引用的使用場景
比如在一個博客管理系統裡,為了提升訪問性能,在用戶在點擊博文時,如果這篇博文沒有緩存到內存中,則需要做緩存動作,這樣其它用戶在點擊同樣這篇文章時,就能直接從內存裡裝載,而不用走數據庫,這樣能降低響應時間。
我們可以通過數據庫級別的緩存在做到這點,這裡也可以通過軟引用來實現,具體的實現步驟如下:
1、可以通過定義Content類來封裝博文的內容,其中可以包括文章ID、文章內容、作者、發表時間和引用圖片等相關信息。
2、可以定義一個類型為HashMap
3、當用戶點擊某個ID的文章時,根據ID到第二步定義的HashMap裡去找,如果找到,而且所對應的SoftReference
4、如果用戶點擊的某個文章的ID在HashMap裡找不到,或者雖然找到,但對應的值內容是空,那麼就從數據庫去找,找到後顯示這個文章,同時再把它插入到HashMap裡,這裡請注意,顯示後需要撤銷掉這個Content類型對象上的強引用,保證它上面只有一個軟引用。
來分析下用軟引用有什麼好處?
假設我們用1個G的空間緩存了10000篇文章,這10000篇文章所佔的內存空間上只有軟引用。如果內存空間足夠,那麼我們可以通過緩存來提升性能,但萬一內存空間不夠,我們可以依次釋放這10000篇文章所佔的1G內存,釋放後不會影響業務流程,最多就是降低些性能。
對比一下,如果我們這裡不用軟應用,而是用強引用來緩存,由於不知道文章何時將被點擊,我們還無法得知什麼時候可以撤銷這些文章對象上的強引用,或者即使我們引入了一套緩存淘汰流程,但這就是額外的工作了,這就沒剛才使用“軟引用“那樣方便了。
三、通過WeakHashMap來了解弱引用的使用場景
WeakHashMap和HashMap很相似,可以存儲鍵值對類型的對象,但我們可以從它的名字上看出,其中的引用是弱引用。通過下面的WeakHashMapDemo.java,我們來看下它的用法。
通過下表,我們來詳細說明關鍵代碼的含義:
根據上文和這裡的描述,我們知道如果當一個對象上只有弱引用時,這個對象會在下次垃圾回收時被回收,下面我們給出一個弱引用的使用場景。
比如在某個電商網站項目裡,我們會用Coupan這個類來保存優惠券信息,在其中我們可以定義優惠券的打折程度,有效日期和所作用的商品範圍等信息。當我們從數據庫裡得到所有的優惠券信息後,會用一個List
而且,我們想要用一種數據結構來保存一個優惠券對象以及它所關聯的所有用戶,這時我們可以用WeakHashMap
大家可以想象下,如果有100個優惠券,那麼它們會存儲於List
這樣的話,一旦當優惠券或用戶發生變更,它們的對應關係就能自動地更新,具體表現如下:
1、當某個優惠券(假設對應於coupan2對象)失效時,我們可以從coupanList裡去除該對象,coupan2上就沒有強引用了,只有weakCoupanHM對該對象還有個弱引用,這樣coupan2對象能在下次垃圾回收時被回收,從而weakCoupanHM裡就看不到了。
2、假設某個優惠券coupan3用弱引用的方式指向於100個用戶,當某個用戶(假設user1)註銷賬號時,它會被從List
如果不用弱引用,而是用常規的HashMap
四、不能投機取巧,但面試確實有技巧
筆者寫本文的意思,不是讓大家投機取巧,事實上,如果大家只知道這些知識,而不知道其他虛擬機(或Java Core)相關的知識點,面試通過的可能性很低。
但話說回來,如果大家在平時開發時積累了很多經驗,但不會總結,在面試時也無法很好地展示各種能力,這樣也是非常可惜的。
根據本人在培訓學校的經驗,首先通過可能掌握各種Java技能,在這個基礎上再講述上述軟引用和弱引用的技能,這些候選人得到的反饋是,至少在Java Core方面比較精通。
原文地址:http://www.cnblogs.com/JavaArchitect/p/8685993.html
閱讀更多 3T教育編程猿 的文章