java虛擬機(jī)內(nèi)存管理機(jī)制:內(nèi)存管理與垃圾回收
- 作者:新網(wǎng)
- 來源:新網(wǎng)
- 瀏覽:100
- 2018-05-12 10:50:33
java語言具有垃圾回收的能力,內(nèi)存管理不需要應(yīng)用程序去過問,這對(duì)于我們來說非常方便。但是,垃圾回收是怎么進(jìn)行的,VM的內(nèi)存參數(shù)應(yīng)該怎么調(diào)整,如何優(yōu)化,往往我們不是太清楚。小編接下就帶大家了解一下吧。
java語言具有垃圾回收的能力,內(nèi)存管理不需要應(yīng)用程序去過問,這對(duì)于我們來說非常方便。但是,垃圾回收是怎么進(jìn)行的,VM的內(nèi)存參數(shù)應(yīng)該怎么調(diào)整,如何優(yōu)化,往往我們不是太清楚。小編接下就帶大家了解一下吧。
<
div> 當(dāng)JVM進(jìn)行GC的時(shí)候,是要消耗CPU資源和需要一定時(shí)間的,這會(huì)影響到程序的正常運(yùn)行,因此需要盡可能減少GC消耗的時(shí)間。Java程序運(yùn)行過程中,對(duì)象的生命周期有長有短,其中相當(dāng)大部分是都是比較短命的,例如局部的對(duì)象一用完就可以回收了。在大多數(shù)情況下,只要能夠及時(shí)回收這些短命對(duì)象的內(nèi)存,就能夠確保JVM有足夠內(nèi)存來分配給新的對(duì)象。因此JVM采用一種分代回收(generational collection) 的策略,用較高的頻率對(duì)年輕的對(duì)象(young generation)進(jìn)行掃描和回收,這種叫做minor collection,而對(duì)老對(duì)象(old generation)的檢查回收頻率要低很多,稱為major collection。這樣就不需要每次GC都將內(nèi)存中所有對(duì)象都檢查一遍。
Sun JVM 1.3 有兩種最基本的內(nèi)存收集方式:一種稱為copying或scavenge,將所有仍然生存的對(duì)象搬到另外一塊內(nèi)存后,整塊內(nèi)存就可回收。這種方法有效率,但需要有一定的空閑內(nèi)存,拷貝也有開銷。這種方法用于minor collection。另外一種稱為mark-compact,將活著的對(duì)象標(biāo)記出來,然后搬遷到一起連成大塊的內(nèi)存,其他內(nèi)存就可以回收了。這種方法不需要占用額外的
空間,但速度相對(duì)慢一些。這種方法用于major collection。
在JVM 1.3及以后的版本中,還有其他可選的內(nèi)存收集方法,通過特定的參數(shù)來設(shè)定。例如:增量式回收,每次只處理一小部分;替代單線程copying的多線程并行回收;替代mark-compact的concurrent mark-sweep回收等等。參考資料[4][5]中有更多描述。
JVM管理的內(nèi)存,通常叫做堆(heap),JVM啟動(dòng)后,保留一段地址空間,這個(gè)空間的大小由-Xmx指定。這塊空間的大小就是heap可能的最大值,但一開始不一定全都分配了物理內(nèi)存,初始分配的heap大小由-Xms指定,如果-Xms小于-Xmx,剩余部分是virtual的,當(dāng)需要的時(shí)候,再向OS申請(qǐng)。而且申請(qǐng)之后,是繼續(xù)占用而不釋放給該jvm以外的程序。比如你的jvm申請(qǐng)了1G的內(nèi)存,剛開始用了200M,然后隨著程序的進(jìn)行,內(nèi)存用到900M,然后進(jìn)行垃圾回收,想釋放一些內(nèi)存給其他程序,這是不可以的,此時(shí),jvm依然會(huì)保有著900M內(nèi)存。
綠色部分是young generation的內(nèi)存,由一塊Eden(伊甸園,有意思)和兩塊Survivor Space(1.4文檔中稱為semi-space)構(gòu)成。新創(chuàng)建的對(duì)象的內(nèi)存都分配自eden。兩塊Survivor Space總有會(huì)一塊是空閑的,用作copying collection的目標(biāo)空間。Minor collection的過程就是將eden和在用survivor space中的活對(duì)象copy到空閑survivor space中。所謂survivor,也就是大部分對(duì)象在伊甸園出生后,根本活不過一次GC。對(duì)象在young generation里經(jīng)歷了一定次數(shù)的minor collection后,年紀(jì)大了,就會(huì)被移到old generation中,稱為tenuring。(是否僅當(dāng)survivor space不足的時(shí)候才會(huì)將老對(duì)象tenuring? 目前資料中沒有找到描述)
淺藍(lán)色部分是old generation的內(nèi)存。
深藍(lán)色部分稱為permanent generation,是JVM用來保存class object和meta data,大小由-XX:PermSize和-XX:MaxPermSize指定。大量動(dòng)態(tài)生成(編譯)和加載class會(huì)增加這部分內(nèi)存的耗用。
剩余內(nèi)存空間不足會(huì)觸發(fā)GC,如eden空間不夠了就要進(jìn)行minor collection,old generation空間不夠要進(jìn)行major collection,permanent generation空間不足會(huì)引發(fā)full GC。
以上就是小編對(duì)于垃圾回收的了解了,大家可以留言哦。
很多參數(shù)會(huì)影響里面各部分空間的分配。-XX:MinHeapFreeRatio與-XX:MaxHeapFreeRatio設(shè)定空閑內(nèi)存占總內(nèi)存的比例范圍,這兩個(gè)參數(shù)會(huì)影響GC的頻率和單次GC的耗時(shí)。-XX:NewRatio決定young與old generation的比例。Young generation空間越大,minor collection頻率越低,但是old generation空間小了,又可能導(dǎo)致major collection頻率增加。-XX:NewSize和-XX:MaxNewSize直接指定了young generation的缺省大小和最大大小。