亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

Java中內(nèi)存問(wèn)題之OOM詳解

 更新時(shí)間:2023年08月22日 09:28:58   作者:ycfxhsw  
這篇文章主要介紹了Java中內(nèi)存管理的OOM詳解,OOM,全稱“Out?Of?Memory”,翻譯成中文就是“內(nèi)存用完了”,來(lái)源于java.lang.OutOfMemoryError,當(dāng)JVM因?yàn)闆](méi)有足夠的內(nèi)存來(lái)為對(duì)象分配空間并且垃圾回收器也已經(jīng)沒(méi)有空間可回收時(shí),就會(huì)拋出這個(gè)error,需要的朋友可以參考下

一. StackOverflowError

1.1 bug

public class StackOverflowErrorDemo {
    public static void main(String[] args) {
        javaKeeper();
    }
    private static void javaKeeper() {
        javaKeeper();
    }
}

JVM 虛擬機(jī)棧是有深度的,在執(zhí)行方法的時(shí)候會(huì)伴隨著入棧和出棧,上邊的方法可以看到,main 方法執(zhí)行后不停的遞歸,遲早把棧撐爆了

Exception in thread "main" java.lang.StackOverflowError
	at oom.StackOverflowErrorDemo.javaKeeper(StackOverflowErrorDemo.java:15)

1.2 原因分析

  • 無(wú)限遞歸循環(huán)調(diào)用(最常見(jiàn)原因),要時(shí)刻注意代碼中是否有了循環(huán)調(diào)用方法而無(wú)法退出的情況
  • 執(zhí)行了大量方法,導(dǎo)致線程??臻g耗盡
  • 方法內(nèi)聲明了海量的局部變量
  • native 代碼有棧上分配的邏輯,并且要求的內(nèi)存還不小,比如 java.net.SocketInputStream.read0 會(huì)在棧上要求分配一個(gè) 64KB 的緩存(64位 Linux)

1.3 解決方案

  • 修復(fù)引發(fā)無(wú)限遞歸調(diào)用的異常代碼, 通過(guò)程序拋出的異常堆棧,找出不斷重復(fù)的代碼行,按圖索驥,修復(fù)無(wú)限遞歸 Bug
  • 排查是否存在類之間的循環(huán)依賴(當(dāng)兩個(gè)對(duì)象相互引用,在調(diào)用toString方法時(shí)也會(huì)產(chǎn)生這個(gè)異常)
  • 通過(guò) JVM 啟動(dòng)參數(shù) -Xss 增加線程棧內(nèi)存空間, 某些正常使用場(chǎng)景需要執(zhí)行大量方法或包含大量局部變量,這時(shí)可以適當(dāng)?shù)靥岣呔€程??臻g限制

二. Java heap space

Java 堆用于存儲(chǔ)對(duì)象實(shí)例,我們只要不斷的創(chuàng)建對(duì)象,并且保證 GC Roots 到對(duì)象之間有可達(dá)路徑來(lái)避免 GC 清除這些對(duì)象,那隨著對(duì)象數(shù)量的增加,總?cè)萘坑|及堆的最大容量限制后就會(huì)產(chǎn)生內(nèi)存溢出異常。

Java 堆內(nèi)存的 OOM 異常是實(shí)際應(yīng)用中最常見(jiàn)的內(nèi)存溢出異常。

2.1 bug

/** * JVM參數(shù)&#xff1a;-Xmx12m */public class JavaHeapSpaceDemo {<!-- -->    static final int SIZE &#61; 2 * 1024 * 1024;    public static void main(String[] a) {<!-- -->        int[] i &#61; new int[SIZE];    }}

代碼試圖分配容量為 2M 的 int 數(shù)組,如果指定啟動(dòng)參數(shù) -Xmx12m ,分配內(nèi)存就不夠用,就類似于將 XXXL 號(hào)的對(duì)象,往 S 號(hào)的 Java heap space 里面塞。

/**
 * JVM參數(shù):-Xmx12m
 */
public class JavaHeapSpaceDemo {
    static final int SIZE = 2 * 1024 * 1024;
    public static void main(String[] a) {
        int[] i = new int[SIZE];
    }
}

2.2 原因分析

  • 請(qǐng)求創(chuàng)建一個(gè)超大對(duì)象,通常是一個(gè)大數(shù)組
  • 超出預(yù)期的訪問(wèn)量/數(shù)據(jù)量,通常是上游系統(tǒng)請(qǐng)求流量飆升,常見(jiàn)于各類促銷/秒殺活動(dòng),可以結(jié)合業(yè)務(wù)流量指標(biāo)排查是否有尖狀峰值
  • 過(guò)度使用終結(jié)器(Finalizer),該對(duì)象沒(méi)有立即被 GC
  • 內(nèi)存泄漏(Memory Leak),大量對(duì)象引用沒(méi)有釋放,JVM 無(wú)法對(duì)其自動(dòng)回收,常見(jiàn)于使用了 File 等資源沒(méi)有回收

2.3 解決方案

針對(duì)大部分情況,通常只需要通過(guò) -Xmx 參數(shù)調(diào)高 JVM 堆內(nèi)存空間即可。如果仍然沒(méi)有解決,可以參考以下情況做進(jìn)一步處理:

  • 如果是超大對(duì)象,可以檢查其合理性,比如是否一次性查詢了數(shù)據(jù)庫(kù)全部結(jié)果,而沒(méi)有做結(jié)果數(shù)限制
  • 如果是業(yè)務(wù)峰值壓力,可以考慮添加機(jī)器資源,或者做限流降級(jí)。
  • 如果是內(nèi)存泄漏,需要找到持有的對(duì)象,修改代碼設(shè)計(jì),比如關(guān)閉沒(méi)有釋放的連接

內(nèi)存泄露和內(nèi)存溢出

內(nèi)存溢出(out of memory),是指程序在申請(qǐng)內(nèi)存時(shí),沒(méi)有足夠的內(nèi)存空間供其使用,出現(xiàn)out of memory;

比如申請(qǐng)了一個(gè) Integer,但給它存了 Long 才能存下的數(shù),那就是內(nèi)存溢出。

內(nèi)存泄露( memory leak),是指程序在申請(qǐng)內(nèi)存后,無(wú)法釋放已申請(qǐng)的內(nèi)存空間,一次內(nèi)存泄露危害可以忽略,但內(nèi)存泄露堆積后果很嚴(yán)重,無(wú)論多少內(nèi)存,遲早會(huì)被占光。

memory leak 最終會(huì)導(dǎo)致 out of memory!

到此這篇關(guān)于Java中內(nèi)存管理的OOM詳解的文章就介紹到這了,更多相關(guān)Java的OOM內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 詳解java線程的開(kāi)始、暫停、繼續(xù)

    詳解java線程的開(kāi)始、暫停、繼續(xù)

    本文將介紹通過(guò)線程讀取文件內(nèi)容,并且可以控制線程的開(kāi)始、暫停、繼續(xù),來(lái)控制讀文件。具有一定的參考作用,下面跟著小編一起來(lái)看下吧
    2017-01-01
  • Kotlin委托機(jī)制使用方式和原理解析

    Kotlin委托機(jī)制使用方式和原理解析

    委托類(代理類)持有真實(shí)類的對(duì)象,然后委托類(代理類)調(diào)用真實(shí)類的同名方法,最終真正實(shí)現(xiàn)的是方法的是真實(shí)類,這其實(shí)就是代理模式,下面通過(guò)本文給大家介紹Kotlin委托機(jī)制使用方式和原理解析,感興趣的朋友一起看看吧
    2025-06-06
  • 劍指Offer之Java算法習(xí)題精講二叉樹(shù)的構(gòu)造和遍歷

    劍指Offer之Java算法習(xí)題精講二叉樹(shù)的構(gòu)造和遍歷

    跟著思路走,之后從簡(jiǎn)單題入手,反復(fù)去看,做過(guò)之后可能會(huì)忘記,之后再做一次,記不住就反復(fù)做,反復(fù)尋求思路和規(guī)律,慢慢積累就會(huì)發(fā)現(xiàn)質(zhì)的變化
    2022-03-03
  • JVM堆內(nèi)存溢出后,其他線程是否可繼續(xù)工作的問(wèn)題解析

    JVM堆內(nèi)存溢出后,其他線程是否可繼續(xù)工作的問(wèn)題解析

    這篇文章主要介紹了JVM 堆內(nèi)存溢出后,其他線程是否可繼續(xù)工作?,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2019-08-08
  • springboot 中 druid+jpa+MYSQL數(shù)據(jù)庫(kù)配置過(guò)程

    springboot 中 druid+jpa+MYSQL數(shù)據(jù)庫(kù)配置過(guò)程

    這篇文章主要介紹了springboot 中 druid+jpa+MYSQL數(shù)據(jù)庫(kù)配置,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2021-08-08
  • Java中try、catch的使用方法

    Java中try、catch的使用方法

    這篇文章主要介紹了Java中try、catch的使用方法,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-06-06
  • 基于spring三方包類注入容器的四種方式小結(jié)

    基于spring三方包類注入容器的四種方式小結(jié)

    這篇文章主要介紹了基于spring三方包類注入容器的四種方式小結(jié),具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2020-09-09
  • Springboot MongoDB實(shí)現(xiàn)自增序列的項(xiàng)目實(shí)踐

    Springboot MongoDB實(shí)現(xiàn)自增序列的項(xiàng)目實(shí)踐

    在某些特定的業(yè)務(wù)場(chǎng)景下,會(huì)需要使用自增的序列來(lái)維護(hù)數(shù)據(jù),本文主要介紹了Springboot MongoDB實(shí)現(xiàn)自增序列的項(xiàng)目實(shí)踐,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2023-07-07
  • 策略模式:告別if else

    策略模式:告別if else

    你是不是還在寫著大量的if else語(yǔ)句,if else 不僅難以維護(hù)不易擴(kuò)展,而且使代碼臃腫不堪,想不想讓你的業(yè)務(wù)代碼更加的健壯,更易擴(kuò)展,那你一定要學(xué)一學(xué)今天的主角策略模式
    2021-06-06
  • Java開(kāi)發(fā)崗位面試被問(wèn)到反射怎么辦

    Java開(kāi)發(fā)崗位面試被問(wèn)到反射怎么辦

    這篇文章主要介紹了java 面向?qū)ο竺嬖嚰\的相關(guān)資料,這里整理了面向?qū)ο蟮幕A(chǔ)知識(shí),幫助大家學(xué)習(xí)理解此部分的知識(shí),需要的朋友可以參考下
    2021-07-07

最新評(píng)論