JVM內(nèi)存模型以及垃圾收集策略解析_第1頁
JVM內(nèi)存模型以及垃圾收集策略解析_第2頁
JVM內(nèi)存模型以及垃圾收集策略解析_第3頁
JVM內(nèi)存模型以及垃圾收集策略解析_第4頁
JVM內(nèi)存模型以及垃圾收集策略解析_第5頁
已閱讀5頁,還剩8頁未讀 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報或認(rèn)領(lǐng)

文檔簡介

1、一JVM內(nèi)存模型 Java棧 Java棧是與每一個線程關(guān)聯(lián)的,JVM在創(chuàng)建每一個線程的時候,會分配一定的棧空間給線程。它主要用來存儲線程執(zhí)行過程中的局部變量,方法的返回值,以及方法調(diào)用上下文。??臻g隨著線程的終止而釋放。StackOverflowError:如果在線程執(zhí)行的過程中,棧空間不夠用,那么JVM就會拋出此異常,這種情況一般是死遞歸造成的。堆 Java中堆是由所有的線程共享的一塊內(nèi)存區(qū)域,堆用來保存各種JAVA對象,比如數(shù)組,線程對象等。Generation JVM堆一般又可以分為以下三部分:PermPerm代主要保存class,method,filed對象,這部門的空間一般不會溢出,

2、除非一次性加載了很多的類,不過在涉及到熱部署的應(yīng)用服務(wù)器的時候,有時候會遇到j(luò)ava.lang.OutOfMemoryError:PermGenspace的錯誤,造成這個錯誤的很大原因就有可能是每次都重新部署,但是重新部署后,類的class沒有被卸載掉,這樣就造成了大量的class對象保存在了perm中,這種情況下,一般重新啟動應(yīng)用服務(wù)器可以解決問題。TenuredTenured區(qū)主要保存生命周期長的對象,一般是一些老的對象,當(dāng)一些對象在Young復(fù)制轉(zhuǎn)移一定的次數(shù)以后,對象就會被轉(zhuǎn)移到Tenured區(qū),一般如果系統(tǒng)中用了application級別的緩存,緩存中的對象往往會被轉(zhuǎn)移到這一區(qū)間。Y

3、oungYoung區(qū)被劃分為三部分,Eden區(qū)和兩個大小嚴(yán)格相同的Survivor區(qū),其中Survivor區(qū)間中,某一時刻只有其中一個是被使用的,另外一個留做垃圾收集時復(fù)制對象用,在Young區(qū)間變滿的時候,minorGC就會將存活的對象移到空閑的Survivor區(qū)間中,根據(jù)JVM的策略,在經(jīng)過幾次垃圾收集后,任然存活于Survivor的對象將被移動到Tenured區(qū)間。SizingtheGenerations JVM提供了相應(yīng)的參數(shù)來對內(nèi)存大小進(jìn)行配置。正如上面描述,JVM中堆被分為了3個大的區(qū)間,同時JVM也提供了一些選項對Young,Tenured的大小進(jìn)行控制。TotalHeap-Xm

4、s:指定了JVM初始啟動以后初始化內(nèi)存-Xmx:指定JVM堆得最大內(nèi)存,在JVM啟動以后,會分配-Xmx參數(shù)指定大小的內(nèi)存給JVM,但是不一定全部使用,JVM會根據(jù)-Xms參數(shù)來調(diào)節(jié)真正用于JVM的內(nèi)存-Xmx-Xms之差就是三個Virtual空間的大小YoungGeneration-XX:NewRatio=8意味著tenured和young的比值8:1,這樣eden+2*survivor=1/9堆內(nèi)存-XX:SurvivorRatio=32意味著eden和一個survivor的比值是32:1,這樣一個Survivor就占Young區(qū)的1/34.-Xmn參數(shù)設(shè)置了年輕代的大小PermGener

5、ation-XX:PermSize=16M-XX:MaxPermSize=64MThreadStack-XX:Xss=128K堆棧分離的好處 呵 呵,其它的先不說了,就來說說面向?qū)ο蟮脑O(shè)計吧,當(dāng)然除了面向?qū)ο蟮脑O(shè)計帶來的維護(hù)性,復(fù)用性和擴(kuò)展性方面的好處外,我們看看面向?qū)ο笕绾吻擅畹睦昧硕?棧分離。如果從JAVA內(nèi)存模型的角度去理解面向?qū)ο蟮脑O(shè)計,我們就會發(fā)現(xiàn)對象它完美的表示了堆和棧,對象的數(shù)據(jù)放在堆中,而我們編寫的那些方法一般都是 運(yùn)行在棧中,因此面向?qū)ο蟮脑O(shè)計是一種非常完美的設(shè)計方式,它完美的統(tǒng)一了數(shù)據(jù)存儲和運(yùn)行。二JAVA垃圾收集器 垃圾收集簡史 垃圾收集提供了內(nèi)存管理的機(jī)制,使得應(yīng)用程

6、序不需要在關(guān)注內(nèi)存如何釋放,內(nèi)存用完后,垃圾收集會進(jìn)行收集,這樣就減輕了因為人為的管理內(nèi)存而造成的錯誤,比如在C+語言里,出現(xiàn)內(nèi)存泄露時很常見的。Java語言是目前使用最多的依賴于垃圾收集器的語言,但是垃圾收集器策略從20世紀(jì)60年代就已經(jīng)流行起來了,比如Smalltalk,Eiffel等編程語言也集成了垃圾收集器的機(jī)制。常見的垃圾收集策略 所有的垃圾收集算法都面臨同一個問題,那就是找出應(yīng)用程序不可到達(dá)的內(nèi)存塊,將其釋放,這里面得不可到達(dá)主要是指應(yīng)用程序已經(jīng)沒有內(nèi)存塊的引用了,而在JAVA中,某個對象對應(yīng)用程序是可到達(dá)的是指:這個對象被根(根主要是指類的靜態(tài)變量,或者活躍在所有線程棧的對象的引

7、用)引用或者對象被另一個可到達(dá)的對象引用。ReferenceCounting(引用計數(shù)) 引用計數(shù)是最簡單直接的一種方式,這種方式在每一個對象中增加一個引用的計數(shù),這個計數(shù)代表當(dāng)前程序有多少個引用引用了此對象,如果此對象的引用計數(shù)變?yōu)?,那么此對象就可以作為垃圾收集器的目標(biāo)對象來收集。優(yōu)點(diǎn):簡單,直接,不需要暫停整個應(yīng)用缺點(diǎn):1.需要編譯器的配合,編譯器要生成特殊的指令來進(jìn)行引用計數(shù)的操作,比如每次將對象賦值給新的引用,或者者對象的引用超出了作用域等。跟蹤收集器 跟蹤收集器首先要暫停整個應(yīng)用程序,然后開始從根對象掃描整個堆,判斷掃描的對象是否有對象引用,這里面有三個問題需要搞清楚:1如果每次掃

8、描整個堆,那么勢必讓GC的時間變長,從而影響了應(yīng)用本身的執(zhí)行。因此在JVM里面采用了分代收集,在新生代收集的時候minorgc只需要掃描新生代,而不需要掃描老生代。2JVM采用了分代收集以后,minorgc只掃描新生代,但是minorgc怎么判斷是否有老生代的對象引用了新生代的對象,JVM采用了卡片標(biāo)記的策略,卡片標(biāo)記將老生代分成了一塊一塊的,劃分以后的每一個塊就叫做一個卡片,JVM采用卡表維護(hù)了每一個塊的狀態(tài),當(dāng)JAVA程序運(yùn)行的時候,如果發(fā)現(xiàn)老生代對象引用或者釋放了新生代對象的引用,那么就JVM就將卡表的狀態(tài)設(shè)置為臟狀態(tài),這樣每次minorgc的時候就會只掃描被標(biāo)記為臟狀態(tài)的卡片,而不需要

9、掃描整個堆。具體如下圖:3GC在收集一個對象的時候會判斷是否有引用指向?qū)ο?,在JAVA中的引用主要有四種:Strongreference,Softreference,Weakreference,Phantomreference.StrongReference強(qiáng)引用是JAVA中默認(rèn)采用的一種方式,我們平時創(chuàng)建的引用都屬于強(qiáng)引用。如果一個對象沒有強(qiáng)引用,那么對象就會被回收。publicvoidtestStrongReference()Objectreferent=newObject();ObjectstrongReference=referent;referent=null;System.gc()

10、;assertNotNull(strongReference);SoftReference軟引用的對象在GC的時候不會被回收,只有當(dāng)內(nèi)存不夠用的時候才會真正的回收,因此軟引用適合緩存的場合,這樣使得緩存中的對象可以盡量的再內(nèi)存中待長久一點(diǎn)。PublicvoidtestSoftReference()Stringstr=test;SoftReferencesoftreference=newSoftReference(str);str=null;System.gc();assertNotNull(softreference.get();Weakreference弱引用有利于對象更快的被回收,假如一個

11、對象沒有強(qiáng)引用只有弱引用,那么在GC后,這個對象肯定會被回收。PublicvoidtestWeakReference()Stringstr=test;WeakReferenceweakReference=newWeakReference(str);str=null;System.gc();assertNull(weakReference.get();PhantomreferenceMark-SweepCollector(標(biāo)記-清除收集器) 標(biāo)記清除收集器最早由Lisp的發(fā)明人于1960年提出,標(biāo)記清除收集器停止所有的工作,從根掃描每個活躍的對象,然后標(biāo)記掃描過的對象,標(biāo)記完成以后,清除那些沒有

12、被標(biāo)記的對象。優(yōu)點(diǎn):1解決循環(huán)引用的問題2不需要編譯器的配合,從而就不執(zhí)行額外的指令缺點(diǎn):1每個活躍的對象都要進(jìn)行掃描,收集暫停的時間比較長。CopyingCollector(復(fù)制收集器) 復(fù)制收集器將內(nèi)存分為兩塊一樣大小空間,某一個時刻,只有一個空間處于活躍的狀態(tài),當(dāng)活躍的空間滿的時候,GC就會將活躍的對象復(fù)制到未使用的空間中去,原來不活躍的空間就變?yōu)榱嘶钴S的空間。復(fù)制收集器具體過程可以參考下圖:優(yōu)點(diǎn):1只掃描可以到達(dá)的對象,不需要掃描所有的對象,從而減少了應(yīng)用暫停的時間缺點(diǎn):1需要額外的空間消耗,某一個時刻,總是有一塊內(nèi)存處于未使用狀態(tài)2復(fù)制對象需要一定的開銷Mark-CompactCol

13、lector(標(biāo)記-整理收集器) 標(biāo)記整理收集器汲取了標(biāo)記清除和復(fù)制收集器的優(yōu)點(diǎn),它分兩個階段執(zhí)行,在第一個階段,首先掃描所有活躍的對象,并標(biāo)記所有活躍的對象,第二個階段首先清除未標(biāo)記的對象,然后將活躍的的對象復(fù)制到堆得底部。標(biāo)記整理收集器的過程示意圖請參考下圖:Mark-compact策略極大的減少了內(nèi)存碎片,并且不需要像CopyCollector一樣需要兩倍的空間。JVM的垃圾收集策略 GC的執(zhí)行時要耗費(fèi)一定的CPU資源和時間的,因此在以后,JVM引入了分代收集的策略,其中對新生代采用Mark-Compact策略,而對老生代采用了“Mark-Sweep的策略。其中新生代的垃圾收集器命名為“

14、minorgc”,老生代的GC命名為FullGc或者M(jìn)ajorGC.其中用System.gc()強(qiáng)制執(zhí)行的是FullGc.SerialCollector SerialCollector是指任何時刻都只有一個線程進(jìn)行垃圾收集,這種策略有一個名字“stopthewholeworld,它需要停止整個應(yīng)用的執(zhí)行。這種類型的收集器適合于單CPU的機(jī)器。SerialCopyingCollector此種GC用-XX:UseSerialGC選項配置,它只用于新生代對象的收集。以后.-XX:MaxTenuringThreshold來設(shè)置對象復(fù)制的次數(shù)。當(dāng)eden空間不夠的時候,GC會將eden的活躍對象和一個名

15、叫Fromsurvivor空間中尚不夠資格放入Old代的對象復(fù)制到另外一個名字叫ToSurvivor的空間。而此參數(shù)就是用來說明到底Fromsurvivor中的哪些對象不夠資格,假如這個參數(shù)設(shè)置為31,那么也就是說只有對象復(fù)制31次以后才算是有資格的對象。這里需要注意幾個個問題:FromSurvivor和Tosurvivor的角色是不斷的變化的,同一時間只有一塊空間處于使用狀態(tài),這個空間就叫做FromSurvivor區(qū),當(dāng)復(fù)制一次后角色就發(fā)生了變化。如果復(fù)制的過程中發(fā)現(xiàn)Tosurvivor空間已經(jīng)滿了,那么就直接復(fù)制到oldgeneration.比較大的對象也會直接復(fù)制到Oldgenerati

16、on,在開發(fā)中,我們應(yīng)該盡量避免這種情況的發(fā)生。SerialMark-CompactCollector串行的標(biāo)記-整理收集器是JDK5update6之前默認(rèn)的老生代的垃圾收集器,此收集使得內(nèi)存碎片最少化,但是它需要暫停的時間比較長2.3.2ParallelCollector ParallelCollector主要是為了應(yīng)對多CPU,大數(shù)據(jù)量的環(huán)境。ParallelCollector又可以分為以下兩種:ParallelCopyingCollector此種GC用-XX:UseParNewGC參數(shù)配置,它主要用于新生代的收集,此GC可以配合CMS一起使用。以后ParallelMark-CompactCollector此種GC用-XX:UseParallelOldGC參數(shù)配置,此GC主要用于老生代對象的收集。ParallelscavengingCollector此種GC用-XX:UseParallelGC參數(shù)配置,它是對新生代對象的垃圾收

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論