單例模式討論篇:單例模式與垃圾回收

出處:http://blog.csdn.net/zhengzhb/article/details/7331354?

?

? Jvm的垃圾回收機制到底會不會回收掉長時間不用的單例模式對象,這的確是一個比較有爭議性的問題。將這一部分內容單獨成篇的目的也是為了與廣大博友廣泛的討論一下這個問題。為了能讓更多的人看到這篇文章,請各位博友看完文章之后,點一下“頂”,讓本篇文章排名盡量的靠前。筆者在此謝過。

討論命題:當一個單例的對象長久不用時,會不會被jvm的垃圾收集機制回收。

??????? 首先說一下為什么會產生這一疑問,筆者本人再此之前從來沒有考慮過垃圾回收對單例模式的影響,直到去年讀了一本書,《設計模式之禪》秦小波著。在書中提到在j2ee應用中,jvm垃圾回收機制會把長久不用的單例類對象當作垃圾,并在cpu空閑的時候對其進行回收。之前讀過的幾本設計模式的書,包括《java與模式》,書中都沒有提到jvm垃圾回收機制對單例的影響。并且在工作過程中,也沒有過單例對象被回收的經歷,加上工作中很多前輩曾經告誡過筆者:盡量不要聲明太多的靜態屬性,因為這些靜態屬性被加載后不會被釋放。因此對jvm垃圾收集會回收單例對象這一說法持懷疑態度。漸漸地,發現在同事中和網上的技術人員中,對這一問題也基本上是鮮明的對立兩派。那么到底jvm會不會回收長久不用的單例對象呢。

??????? 對這一問題,筆者本人的觀點是:不會回收。

下面給出本人的測試代碼

[java]?view plaincopy
  1. class?Singleton?{??
  2. ????private?byte[]?a?=?new?byte[6*1024*1024];??
  3. ????private?static?Singleton?singleton?=?new?Singleton();??
  4. ????private?Singleton(){}??
  5. ??????
  6. ????public?static?Singleton?getInstance(){??
  7. ????????return?singleton;??
  8. ????}??
  9. }??
  10. ??
  11. class?Obj?{??
  12. ????private?byte[]?a?=?new?byte[3*1024*1024];??
  13. }??
  14. ??
  15. public?class?Client{??
  16. ????public?static?void?main(String[]?args)?throws?Exception{??
  17. ????????Singleton.getInstance();??
  18. ????????while(true){??
  19. ????????????new?Obj();??
  20. ????????}??
  21. ????}??
  22. }??

??????? 本段程序的目的是模擬j2ee容器,首先實例化單例類,這個單例類占6M內存,然后程序進入死循環,不斷的創建對象,逼迫jvm進行垃圾回收,然后觀察垃圾收集信息,如果進行垃圾收集后,內存仍然大于6M,則說明垃圾回收不會回收單例對象。

??????? 運行本程序使用的虛擬機是hotspot虛擬機,也就是我們使用的最多的java官方提供的虛擬機,俗稱jdk,版本是jdk1.6.0_12

??????? 運行時vm arguments參數為:-verbose:gc -Xms20M -Xmx20M,意思是每次jvm進行垃圾回收時顯示內存信息,jvm的內存設為固定20M。

運行結果:

……

[Full GC?18566K->6278K(20352K), 0.0101066 secs]

[GC?18567K->18566K(20352K), 0.0001978 secs]

[Full?GC 18566K->6278K(20352K), 0.0088229 secs]

……

??????? 從運行結果中可以看到總有6M空間沒有被收集。因此,筆者認為,至少在hotspot虛擬機中,垃圾回收是不會回收單例對象的。

??????? 后來查閱了一些相關的資料,hotspot虛擬機的垃圾收集算法使用根搜索算法。這個算法的基本思路是:對任何“活”的對象,一定能最終追溯到其存活在堆棧或靜態存儲區之中的引用。通過一系列名為根(GC Roots)的引用作為起點,從這些根開始搜索,經過一系列的路徑,如果可以到達java堆中的對象,那么這個對象就是“活”的,是不可回收的。可以作為根的對象有:

  • 虛擬機棧(棧楨中的本地變量表)中的引用的對象。
  • 方法區中的類靜態屬性引用的對象。
  • 方法區中的常量引用的對象。
  • 本地方法棧中JNI的引用的對象。

??????? 方法區是jvm的一塊內存區域,用來存放類相關的信息。很明顯,java中單例模式創建的對象被自己類中的靜態屬性所引用,符合第二條,因此,單例對象不會被jvm垃圾收集。

??????? 雖然jvm堆中的單例對象不會被垃圾收集,但是單例類本身如果長時間不用會不會被收集呢?因為jvm對方法區也是有垃圾收集機制的。如果單例類被收集,那么堆中的對象就會失去到根的路徑,必然會被垃圾收集掉。對此,筆者查閱了hotspot虛擬機對方法區的垃圾收集方法,jvm卸載類的判定條件如下:

  • 該類所有的實例都已經被回收,也就是java堆中不存在該類的任何實例。
  • 加載該類的ClassLoader已經被回收。
  • 該類對應的java.lang.Class對象沒有任何地方被引用,無法在任何地方通過反射訪問該類的方法。

??????? 只有三個條件都滿足,jvm才會在垃圾收集的時候卸載類。顯然,單例的類不滿足條件一,因此單例類也不會被卸載。也就是說,只要單例類中的靜態引用指向jvm堆中的單例對象,那么單例類和單例對象都不會被垃圾收集,依據根搜索算法,對象是否會被垃圾收集與未被使用時間長短無關,僅僅在于這個對象是不是“活”的。假如一個對象長久未使用而被回收,那么收集算法應該是最近最長未使用算法,最近最長未使用算法一般用在操作系統的內外存交換中,如果用在虛擬機垃圾回收中,豈不是太不安全了?以上是筆者的觀點。

??????? 因此筆者的觀點是:在hotspot虛擬機1.6版本中,除非人為地斷開單例中靜態引用到單例對象的聯接,否則jvm垃圾收集器是不會回收單例對象的。

??????? 期待各位博友的發言。

?

參考文獻

Java虛擬機規范

Java hotspot虛擬機內存管理

Java編程思想

Java與模式

設計模式

設計模式之禪

深入理解java虛擬機

轉載于:https://www.cnblogs.com/Uinkanade/articles/4013762.html

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/259873.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/259873.shtml
英文地址,請注明出處:http://en.pswp.cn/news/259873.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

inline關鍵字

本文介紹了GCC和C99標準中inline使用上的不同之處。inline屬性在使用的時候,要注意以下兩點:inline關鍵字在GCC參考文檔中僅有對其使用在函數定義(Definition)上的描述,而沒有提到其是否能用于函數聲明(Dec…

springmvc 組合注解

組合注解的意思就是一個注解中包含多個注解。在springmvc 的RestController中,你就可發現. Target(ElementType.TYPE) Retention(RetentionPolicy.RUNTIME) Documented Controller ResponseBody public interface RestController {/*** The value may indicate a su…

人才管理是什么意思_上海托管倉庫外包倉庫管理什么意思

上海托管倉庫外包倉庫管理什么意思上海倉庫托管外包。好的上海倉庫托管是預估好自己的貨物總計有多少個方。車子的體積有多少,然后估算出總計需要多少車需要多少錢,需要怎么裝車、卸貨碼放方式是什么樣的,算出總的費用然后包干給搬家公司。這…

window server 安裝與卸載

安裝window server 程序:C:\Windows\Microsoft.NET\Framework\v2.0.50727\installutil DataUpdateService.exe net start LuceneServer 卸載window server 程序:net stop LuceneServer C:\Windows\Microsoft.NET\Framework\v2.0.50727\installutil /U DataUpdateService.exe …

Makefile學習(二)[第二版]

復雜實例#示例1:在上一個示例的基礎上再增加一個可執行文件03test[修改之處已標紅].PHONY: clean all CC gcc CFLAGS -Wall -gBIN 01test 02test 03testSOURCES $(BIN:.c)OBJECTS $(BIN:.o)all: $(BIN)01test: 01test.o02test: 02test.o03test: 03test.o.c.o:$(CC) $(CFLA…

計算機網絡asp視頻教程,輕輕松松學編程!ASP互動視頻教程

從2006年5月18日開始,PConline將與FIF聯合推出國內網上第一部互動視頻教程:《ASP互動視頻教程》。它預示著一個全新的自助學習時代的到來。盡管相較于傳統的圖文教程,以前的多媒體視頻課件優點非常明顯,但它仍然存在交互性差的缺點…

Oracle查詢和解鎖表

一些ORACLE中的進程被殺掉后,狀態被置為"killed",但是鎖定的資源很長時間不釋放,有時實在沒辦法,只好重啟數據庫。現在提供一種方法解決這種問題,那就是在ORACLE中殺不掉的,在OS一級再殺。1.下面…

三維家可以導入別人的方案嗎_廣州深圳天津形位公差檢測三維缺陷檢測服務

形位公差檢測三維缺陷檢測服務標簽:形位公差檢測 三維缺陷檢測服務 三維缺陷檢測鑄造工藝是一種經濟實惠的毛坯成形方式,對于一些形狀復雜的零件更能顯示出它的經濟性。比如汽車發動機的缸體和缸蓋,船舶螺旋槳以及精致的藝術品等。本期案例的…

計算機缺失esul.dll,SceneUI.ES.dll

我該如何安裝從金山毒霸下載的DLL文件?一:1、從金山毒霸下載壓縮文件。2、將DLL文件解壓到電腦上的某個地方。3、把該文件跟要求使用它的程序放在同一路徑上。注意32位程序需要使用32位的DLL文件,64位程序需要使用64位的DLL文件。否則會出現0…

android+ import R錯誤

import android.R; 在開發過程中有時候eclipse自動導入的包,該包有時候會導致一些奇怪的錯誤,再次出現該問題的時候,把import android.R;刪掉。setContentView(R.layout.secondactivity); //不刪掉 import android R;就會報錯轉載…

一、后臺首頁index.php【dedecms后臺源碼分析】

后臺目錄dede目錄的所有問價的源碼分析 使用的dedecms的版本5.7&#xff08;2012-04-01更新&#xff09; 后臺登陸之后的首頁分析dede/index.php <?php /*** 管理后臺首頁** version $Id: index.php 1 11:06 2010年7月13日Z tianya $* package DedeCMS.Admin…

transferto 文件不存在_文件上傳時,MultipartFile.transferTo() 方法報 FileNotFoundException...

Spring Upload File 報錯FileNotFoundException環境&#xff1a;Springboot2.0.4JDK1.8內嵌 Apache Tomcat/8.5.321、前端代碼前端上傳網頁表單&#xff0c;enctype 和 input 的typefile 即可&#xff0c;使用單文件上傳舉例&#xff1a;圖片2、后端代碼RestControllerRequestM…

對“粘連”footer布局的思考和總結

經典的"粘連"footer布局 參考文章鏈接在文章末尾&#xff0c;簡單的語言總結如下&#xff1a; 經典的“粘連”footer布局就是。我們有一塊內容<main>。當<main>的高度足夠長的時候&#xff0c;緊跟在<main>后面的元素<footer>會跟在<main…

計算機函數公式一等獎怎么算,信息技術應用 用計算機畫函數圖象教案設計(一等獎)...

衛鵬展地區&#xff1a; 湖北省 - 黃岡市 - 英山縣學校&#xff1a;英山縣金鋪鎮金鋪中學 共1課時信息技術應用 用計算機畫函數圖象">信息技術應用 用計算機畫… 初中數學 人教2011課標版 1教學目標1&#xff0e;結合具體情境理解一次函數的意義&#xff0c;能結…

這樣去寫你的 HTML

昨天在 twitter 上說&#xff0c;怎么忍心把頁面寫得這么難用&#xff1f;是的&#xff0c;這個世界還有一群人等著我們創建出來的東西&#xff0c;可以讓他們的生活能過得更容易呢。比如那些需要讀屏軟件的用戶。作為一個前端&#xff0c;我們又怎么會忍心呢。之前就一直想寫這…

iframe懶加載_前端常見問題

原地址&#xff1a;https://blog.csdn.net/Mr_JavaScript/article/details/843110681. flex布局&#xff1a;又叫做彈性布局任何一個容器都可以指定flex布局&#xff0c;如display:flex 或 display:inline-flex注意&#xff1a;設置了flex布局以后&#xff0c;子元素的float&am…

手機運行服務器無響應,《最強蝸牛》服務器無響應怎么辦 服務器無響應解決方法...

導讀最強蝸牛服務器無響應怎么辦&#xff1f;本作在今日迎來了正式的公測&#xff0c;這會導致大批量的玩家同時涌入進來&#xff0c;而服務器也因此而遭受到了非常大的符合&#xff0c;所以會導致后續加入進來的玩家出現服務器無響應進不去的現象。下面就為大家帶...最強蝸牛服…

Android 開源框架Universal-Image-Loader學習

Android 開源框架Universal-Image-Loader完全解析&#xff08;一&#xff09;--- 基本介紹及使用 Android 開源框架Universal-Image-Loader完全解析&#xff08;二&#xff09;--- 圖片緩存策略詳解 Android 開源框架Universal-Image-Loader完全解析&#xff08;三&#xff09;…

自己動手寫操作系統--個人實踐

近期開始看于淵的《自己動手寫操作系統》這本書&#xff0c;剛開始看就發現做系統的引導盤居然是軟盤&#xff01;心里那個汗啊&#xff01; 如今都是U盤了&#xff0c;誰還用軟盤。于是考慮用U盤。 于是開始下面步驟&#xff1a; 1、既然書上說給先要把軟盤做引導盤&#xff0…

蔻馳和mk哪個更大牌_mk和coach哪個好?mk和coach包包是一個檔次嗎?

說到包包&#xff0c;mk和coach可謂是輕奢界的兩大巨頭了。因此&#xff0c;兩個品牌的包包不可避免的會被經常拿來作比較。那么&#xff0c;從各個角度來講mk和coach那款包包更好呢&#xff1f;這兩款包包又有哪些本質上的區別呢&#xff1f;mk和coach哪個好價格對比大致上&am…