日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

关于 OutOfMemoryError 的总结与解决方法

發布時間:2025/3/12 编程问答 18 豆豆
生活随笔 收集整理的這篇文章主要介紹了 关于 OutOfMemoryError 的总结与解决方法 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

引言

本文總結自周志明的《深入理解Java虛擬機》第二章部分內容。

這部分內容,可以為后續性能調優方面的工作起到鋪墊作用。

一、什么是 OutOfMemoryError

OurOfMemory 簡稱“OOM”, 直譯為“內存耗盡”或“內存溢出”,當然,并不是真的內存耗盡了,它指的是 JVM 的幾個邏輯分區的內存不夠用了,無法為新的對象分配空間。

在 JVM 的幾個主要內存分區中(JVM 棧、本地方法棧、計數器、方法區、Java 堆),只有計數器不會出現這種嚴重錯誤,也就是說,我們常說的堆和棧等,都有可能出現 OOM 的問題。

二、Java 堆溢出

由于 Java 中最常見的內存分配就是對象,因此,經常要分配內存用于創建對象的堆區,是出現OOM問題的最常見內存分區。

對于 Java 堆的內存溢出,原因其實非常簡單。因為堆是用于存儲對象的,因此只要不斷地創建對象,并且保證 GC Roots 到對象之間有可達路徑避免垃圾回收機制清除這些對象,那么堆就必然會出現 OOM 問題。

如果要試驗堆上的 OOM ,最快的方法就是將堆的分配大小調的低一些,并且不可擴展。

跟在 java 啟動指令之后的兩個最基本的堆大小分配參數是:-Xms 最小堆內存-Xmx 最大堆內存將這兩個參數的值設置為相同,即可避免堆內存的自動擴展。

案例演示

案例使用 JDK 1.8 ,IDE是 Eclipse,內存分析工具Eclipse Memory Analyzer(簡稱 MAT)(https://www.eclipse.org/mat/downloads.php)

使用如上圖所示的虛擬機參數執行程序,即可發生堆內存的 OOM 錯誤。-XX:+HeapDumpOnOutOfMemoryError 參數可以讓虛擬機在出現內存溢出時Dump(轉儲;傾倒)出當前的內存堆轉儲快照,以便事后進行分析。

dump文件的名稱類似: java_pid31228.hprof,需要使用?MAT 打開并分析。(具體分析過程暫時不做詳細介紹)

總之,當出現堆溢出時,一般的手段是,先通過內存映像分析工具(如Eclipse Memory Analyzer)對 Dump 出來的堆轉儲快照進行分析,重點是確認內存中的對象是否是必要的,也就是要先分清楚到底是出現了內存泄漏(Memory Leak)還是內存溢出(Memory Overflow)。

內存泄漏,表示對象已經無用,但是GC并沒有回收,需要進一步通過工具查看泄漏對象到 GC Roots 的引用鏈,掌握了泄漏對象的類型信息GC Roots 引用鏈 信息,就可以比較準確地定位出泄漏代碼的位置。而內存溢出

內存溢出,表示對象卻是還存活著,導致GC 無法回收“有用的”對象,因此就需要檢查 堆參數(-Xms 、-Xmx),與機器物理內存對比看是否還可以調大,或者從代碼上檢查,是否有對象生命周期過長、持有狀態時間過長的情況,嘗試減少程序運行期的內存消耗。

三、虛擬機棧溢出

在 HotSpot 虛擬機中是不區分 JVM 棧和本地方法棧的。設置本地方法棧大小的參數 -Xoss 實際上并無效果。

棧容量只由 -Xss 參數設定。

Java 虛擬機規范規定了兩種棧異常:

1、如果線程請求的棧深度大于虛擬機所允許的最大深度,拋出 StackOverflowError 異常。

2、如果虛擬機在擴展棧時無法申請到足夠的內存空間,拋出 OutOfMemoryError 異常。

實際上,StackOverflowError 針對的是單獨的虛擬機棧,而 OutOfMemoryError 則描述的是所有虛擬機棧。因為一個應用程序中很可能存在多個線程,因此這樣區分異??赡苁菫榱烁_的描述出現的問題。

相對來說,虛擬機棧內存出現問題多數都是 StackOverflowError,而且,Overflow的話會有錯誤堆??梢蚤喿x,相對比較好找到問題所在。而且,如果使用虛擬機默認參數,棧深度在大多數情況下,達到1000 到 2000 個棧幀完全沒有問題。對于正常的方法調用和遞歸,這個深度應該完全夠用。

因此,如果虛擬機棧發生 OOM ,很可能是由于棧深度過大,換句話說,-Xss 參數值過大。

案例演示

以下代碼可能在Windows上運行會使系統假死,建議將重要文件和工作保存。

由于我的電腦本身執行上面的程序就會出現操作系統假死,因此這里貼出書中的執行結果:

Exception in thread "main" java.lang.OutOfMemoryError: unable to create new native thread

四、方法區和運行時常量池溢出

運行時常量池是方法區的一部分,因此,可以通過常量池溢出來測試這兩個區域的溢出情況。

上面的代碼通過 CGLib 動態生成大量的 Class 加載如 方法區。需要通過maven引入CGLib依賴:

<!-- https://mvnrepository.com/artifact/cglib/cglib --><dependency><groupId>cglib</groupId><artifactId>cglib</artifactId><version>3.2.5</version></dependency>

但是代碼執行后并未出現方法區內存溢出的問題。書中貼出的方法區內存溢出異常報錯如下:

Caused by:java.lang.OutOfMemoryError : PermGen spaceat ...at ...at ...

?

創作挑戰賽新人創作獎勵來咯,堅持創作打卡瓜分現金大獎

總結

以上是生活随笔為你收集整理的关于 OutOfMemoryError 的总结与解决方法的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。