溫馨提示×

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

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

JVM內(nèi)存溢出怎么解決

發(fā)布時(shí)間:2021-12-27 16:56:34 來(lái)源:億速云 閱讀:173 作者:iii 欄目:開發(fā)技術(shù)

本篇內(nèi)容介紹了“JVM內(nèi)存溢出怎么解決”的有關(guān)知識(shí),在實(shí)際案例的操作過(guò)程中,不少人都會(huì)遇到這樣的困境,接下來(lái)就讓小編帶領(lǐng)大家學(xué)習(xí)一下如何處理這些情況吧!希望大家仔細(xì)閱讀,能夠?qū)W有所成!

棧溢出(虛擬機(jī)棧和本地方法棧)

產(chǎn)生原因

  • 在HotSpot中,只能由-Xss參數(shù)來(lái)設(shè)定。因?yàn)樵贖otSpot中不區(qū)分虛擬機(jī)棧和本地方法棧的。

  • 棧溢出時(shí)會(huì)出現(xiàn)兩種異常:StackOverflowError異常和OutOfMemoryError異常。

    • StackOverflowError異常因?yàn)榫€程請(qǐng)求的棧深度大于虛擬機(jī)允許的最大深度。

    • OutOfMemoryError異常發(fā)生在虛擬機(jī)棧內(nèi)存允許動(dòng)態(tài)擴(kuò)展的情況下,當(dāng)擴(kuò)展棧容量無(wú)法申請(qǐng)到足夠的內(nèi)存時(shí)。

  • 因?yàn)镠otSpot是不支持?jǐn)U展的,所在除非在線程創(chuàng)建時(shí)申請(qǐng)內(nèi)存無(wú)法滿足時(shí),才會(huì)出現(xiàn)OutOfMemoryError,其余都是產(chǎn)生StackOverflowError異常。

  • 結(jié)論:給每個(gè)線程的棧分配內(nèi)存不是越大越好??梢赃@么理解,比如總的內(nèi)存是2G,如果一個(gè)線程就占了1.5G,那就。。。。

解決思路

出現(xiàn) StackOverflowError異常時(shí),會(huì)有明確錯(cuò)誤堆??晒┓治?,相對(duì)而言比較容易定位到問(wèn)題所在。

如果使用Hotspot虛擬機(jī)默認(rèn)參數(shù),棧深度在大多數(shù)情況下(因?yàn)槊總€(gè)方法壓人棧的幀大小并不是一樣的,所以只能說(shuō)大多數(shù)情況下)到達(dá)1000~2000 是完全沒(méi)有問(wèn)題,對(duì)于正常的方法調(diào)用(包括不能做尾遞歸優(yōu)化的遞歸調(diào)用),這個(gè)深度應(yīng)該完全夠用了。但是,如果是建立過(guò)多線程導(dǎo)致的內(nèi)存濫出,在不能減少線程數(shù)量或者更換 64 位虛擬機(jī)的情況下,就只能通過(guò)減少最大堆和減少棧容量來(lái)?yè)Q取更多的線程。

堆溢出

產(chǎn)生原因

當(dāng)不斷的創(chuàng)建對(duì)象并避免垃圾回收時(shí),總?cè)萘坑|及最大堆容量時(shí),就會(huì)產(chǎn)生溢出。
運(yùn)行代碼:設(shè)置vm參數(shù)-Xms10m -Xmx10m

public class HeapTest {
    static class OOMObj{

    }
    /**
     * vm arg -Xms10m -Xmx10m -XX:+HeapDumpOnOutOfMemoryError
     */

    public static void main(String[] args) {
        List<OOMObj> oomObjList = new ArrayList<OOMObj>();
        while (true){
            oomObjList.add(new OOMObj());
        }
    }
}

結(jié)果:

JVM內(nèi)存溢出怎么解決

解決思路

首先通過(guò)內(nèi)存映像分析工具確認(rèn)是內(nèi)存泄漏還是內(nèi)存溢出。

  1. 如果是內(nèi)存泄漏,說(shuō)明導(dǎo)致OOM的對(duì)象不是必要的。進(jìn)一步通過(guò)工具查看GC Roots引用鏈。一般可以比較精確的定位。

  2. 如果是內(nèi)存溢出,對(duì)象是必須存活的,那就檢查虛擬機(jī)的堆參數(shù)-Xms、-Xmx設(shè)置,對(duì)比機(jī)器內(nèi)存,看是否還有上調(diào)的空間。再?gòu)拇a上檢查對(duì)象生命周期、持有狀態(tài)時(shí)間、存儲(chǔ)結(jié)構(gòu)是否有設(shè)計(jì)不合理等情況。

方法區(qū)和運(yùn)行時(shí)常量池溢出

產(chǎn)生原因

一個(gè)類要被垃圾收集器回收,條件是比較苛刻的。在經(jīng)常運(yùn)行時(shí)生成大量動(dòng)態(tài)類的應(yīng)用場(chǎng)景里,就應(yīng)該特別關(guān)注了。

解決思路

HotSpot在JDK8中已經(jīng)完全使用元空間代替永久帶。Hotspot提供了一些參數(shù)作為元空間的防御措施,主要包括:

  1. XX:MaxMetaspacesize:設(shè)置元空間最大值,默認(rèn)是-1,即不限制,或者說(shuō)只受限于本地內(nèi)存大小。

  2. -XX:Metaspacesize :指定元空間的初始空間大小,以宇節(jié)為單位,達(dá)到該值就會(huì)觸發(fā)垃圾收集進(jìn)行類型卸載,同時(shí)收集器會(huì)對(duì)該值進(jìn)行調(diào)整:如果釋放了大量的空間,就適當(dāng)降低該值;如果釋放了很少的空間,那么在不超過(guò)-XX:MaxMetaspaceSize(如果設(shè)置了的話)的情況下,適當(dāng)提高該值。

  3. -XX:MinMetaspace Free Ratio:作用是在垃圾收集之后控制最小的元空間剩余容量的百分比,可減少因?yàn)樵臻g不足導(dǎo)致的垃圾收集的頻率。類似的還有-xx:Max-MetaspaceFreeRatio,用于控制最大的元空間剩余容量的百分比。

本機(jī)直接內(nèi)存溢出

產(chǎn)生原因

在直接或間接使用了ByteBuffer中的allocateDirect方法的時(shí)候,而不做clear的時(shí)候就會(huì)出現(xiàn)類似的問(wèn)題。明顯的特征是在Heap Dump文件中不會(huì)看到明顯的異常情況。

解決思路

設(shè)置參數(shù): -XX:MaxDirectMemorySize

“JVM內(nèi)存溢出怎么解決”的內(nèi)容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業(yè)相關(guān)的知識(shí)可以關(guān)注億速云網(wǎng)站,小編將為大家輸出更多高質(zhì)量的實(shí)用文章!

向AI問(wèn)一下細(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