溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

JVM內(nèi)存回收問題的處理方法是什么

發(fā)布時(shí)間:2021-10-23 16:57:32 來源:億速云 閱讀:160 作者:柒染 欄目:編程語言

JVM內(nèi)存回收問題的處理方法是什么,針對(duì)這個(gè)問題,這篇文章詳細(xì)介紹了相對(duì)應(yīng)的分析和解答,希望可以幫助更多想解決這個(gè)問題的小伙伴找到更簡(jiǎn)單易行的方法。

重點(diǎn)討論一下JVM內(nèi)存回收問題的解決方法,通常我們說的JVM內(nèi)存回收總是在指堆內(nèi)存回收,確實(shí)只有堆中的內(nèi)容是動(dòng)態(tài)申請(qǐng)分配的,所以以上對(duì)象的年輕代和年老代都是指的JVM的Heap空間,而持久代則是之前提到的MethodArea,不屬于Heap。

JVM內(nèi)存回收

了解JVM的系統(tǒng)結(jié)構(gòu),再來看看JVM內(nèi)存回收問題了——
Sun的JVMGenerationalCollecting(垃圾回收)原理是這樣的:把對(duì)象分為年青代(Young)、年老代(Tenured)、持久代(Perm),對(duì)不同生命周期的對(duì)象使用不同的算法。(基于對(duì)對(duì)象生命周期分析)

JVM內(nèi)存回收問題的處理方法是什么

如上圖所示,為Java堆中的各代分布。

1.Young(年輕代)

年輕代分三個(gè)區(qū)。一個(gè)Eden區(qū),兩個(gè)Survivor區(qū)。大部分對(duì)象在Eden區(qū)中生成。當(dāng)Eden區(qū)滿時(shí),還存活的對(duì)象將被復(fù)制到Survivor區(qū)(兩個(gè)中的一個(gè)),當(dāng)這個(gè)Survivor區(qū)滿時(shí),此區(qū)的存活對(duì)象將被復(fù)制到另外一個(gè)Survivor區(qū),當(dāng)這個(gè)Survivor去也滿了的時(shí)候,從***個(gè)Survivor區(qū)復(fù)制過來的并且此時(shí)還存活的對(duì)象,將被復(fù)制年老區(qū)(Tenured。需要注意,Survivor的兩個(gè)區(qū)是對(duì)稱的,沒先后關(guān)系,所以同一個(gè)區(qū)中可能同時(shí)存在從Eden復(fù)制過來對(duì)象,和從前一個(gè)Survivor復(fù)制過來的對(duì)象,而復(fù)制到年老區(qū)的只有從***個(gè)Survivor去過來的對(duì)象。而且,Survivor區(qū)總有一個(gè)是空的。

2.Tenured(年老代)

年老代存放從年輕代存活的對(duì)象。一般來說年老代存放的都是生命期較長(zhǎng)的對(duì)象。

3.Perm(持久代)

用于存放靜態(tài)文件,如今Java類、方法等。持久代對(duì)垃圾回收沒有顯著影響,但是有些應(yīng)用可能動(dòng)態(tài)生成或者調(diào)用一些class,例如Hibernate等,在這種時(shí)候需要設(shè)置一個(gè)比較大的持久代空間來存放這些運(yùn)行過程中新增的類。持久代大小通過-XX:MaxPermSize=進(jìn)行設(shè)置。

舉個(gè)例子:當(dāng)在程序中生成對(duì)象時(shí),正常對(duì)象會(huì)在年輕代中分配空間,如果是過大的對(duì)象也可能會(huì)直接在年老代生成(據(jù)觀測(cè)在運(yùn)行某程序時(shí)候每次會(huì)生成一個(gè)十兆的空間用收發(fā)消息,這部分內(nèi)存就會(huì)直接在年老代分配)。年輕代在空間被分配完的時(shí)候就會(huì)發(fā)起內(nèi)存回收,大部分內(nèi)存會(huì)被回收,一部分幸存的內(nèi)存會(huì)被拷貝至Survivor的from區(qū),經(jīng)過多次回收以后如果from區(qū)內(nèi)存也分配完畢,就會(huì)也發(fā)生內(nèi)存回收然后將剩余的對(duì)象拷貝至to區(qū)。等到to區(qū)也滿的時(shí)候,就會(huì)再次發(fā)生內(nèi)存回收然后把幸存的對(duì)象拷貝至年老區(qū)。

通常我們說的JVM內(nèi)存回收總是在指堆內(nèi)存回收,確實(shí)只有堆中的內(nèi)容是動(dòng)態(tài)申請(qǐng)分配的,所以以上對(duì)象的年輕代和年老代都是指的JVM的Heap空間,而持久代則是之前提到的MethodArea,不屬于Heap。

關(guān)于JVM內(nèi)存管理的一些建議

1、手動(dòng)將生成的無用對(duì)象,中間對(duì)象置為null,加快內(nèi)存回收。

2、對(duì)象池技術(shù)如果生成的對(duì)象是可重用的對(duì)象,只是其中的屬性不同時(shí),可以考慮采用對(duì)象池來較少對(duì)象的生成。如果有空閑的對(duì)象就從對(duì)象池中取出使用,沒有再生成新的對(duì)象,大大提高了對(duì)象的復(fù)用率。

3、JVM調(diào)優(yōu)通過配置JVM的參數(shù)來提高垃圾回收的速度,如果在沒有出現(xiàn)內(nèi)存泄露且上面兩種辦法都不能保證JVM內(nèi)存回收時(shí),可以考慮采用JVM調(diào)優(yōu)的方式來解決,不過一定要經(jīng)過實(shí)體機(jī)的長(zhǎng)期測(cè)試,因?yàn)椴煌膮?shù)可能引起不同的效果。如-Xnoclassgc參數(shù)等。

推薦的兩款JVM內(nèi)存檢測(cè)工具

1、jconsoleJDK自帶的內(nèi)存監(jiān)測(cè)工具,路徑j(luò)dkbin目錄下jconsole.exe,雙擊可運(yùn)行。連接方式有兩種,***種是本地方式如調(diào)試時(shí)運(yùn)行的進(jìn)程可以直接連,第二種是遠(yuǎn)程方式,可以連接以服務(wù)形式啟動(dòng)的進(jìn)程。遠(yuǎn)程連接方式是:在目標(biāo)進(jìn)程的jvm啟動(dòng)參數(shù)中添加-Dcom.sun.management.jmxremote.port=1090-Dcom.sun.management.jmxremote.ssl=false-Dcom.sun.management.jmxremote.authenticate=false1090是監(jiān)聽的端口號(hào)具體使用時(shí)要進(jìn)行修改,然后使用IP加端口號(hào)連接即可。通過該工具可以監(jiān)測(cè)到當(dāng)時(shí)內(nèi)存的大小,CPU的使用量以及類的加載,還提供了手動(dòng)gc的功能。優(yōu)點(diǎn)是效率高,速度快,在不影響進(jìn)行運(yùn)行的情況下監(jiān)測(cè)產(chǎn)品的運(yùn)行。缺點(diǎn)是無法看到類或者對(duì)象之類的具體信息。使用方式很簡(jiǎn)單點(diǎn)擊幾下就可以知道功能如何了,確實(shí)有不明白之處可以上網(wǎng)查詢文檔。

2、JProfiler收費(fèi)的工具,但是到處都有破解辦法。安裝好以后按照配置調(diào)試的方式配置好一個(gè)本地的session即可運(yùn)行??梢员O(jiān)測(cè)當(dāng)時(shí)的內(nèi)存、CPU、線程等,能具體的列出內(nèi)存的占用情況,還可以就某個(gè)類進(jìn)行分析。優(yōu)點(diǎn)很多,缺點(diǎn)太影響速度,而且有的類可能無法被織入方法,例如我使用jprofiler時(shí)一直沒有備份成功過,總會(huì)有一些類的錯(cuò)誤。

關(guān)于JVM內(nèi)存回收問題的處理方法是什么問題的解答就分享到這里了,希望以上內(nèi)容可以對(duì)大家有一定的幫助,如果你還有很多疑惑沒有解開,可以關(guān)注億速云行業(yè)資訊頻道了解更多相關(guān)知識(shí)。

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

jvm
AI