?? ???? ???: ????? OOM? ???? ??? ??? ???? ???? ??? ?????? ?? ??? ????
Aug 23, 2023 pm 02:34 PMOOM? ????? ???? ??? ????, ?? ?? ?? JVM ???? ???? ?? ??? ? ????. ? ????? Java ????? OOM? ???? ? ??? ???? ??? ?? ???? ?????.
?? ??? ?? ???? ??? ???, ??? ??? ???? ?? ???? ?????

OOM
OOM? "Out Of Memory"? ???? "Out Of Memory"? ?????. ??? ???????. JVM? ??? ??? ??? ???? ??? ???? ???? ??? ??? ? ??? ?????
OOM? ???? ??? ????? ??? ?? ?????
?? ????. ?? : JVM ??? ???? ??, ??? ???? ?? ?????, JVM ???? ??? ??? ???? ?? ???: ?? ??? ?? ????? ???? ???. ? ?? ???? ?? ??? ??? ?????
??? ??: ??? ???? ???? ?? ?? ???? ?? ???? ?? ??? ? ?? ???. ?? ? ???? ?????. . ???? ? ?? ???? ??? ????? ?? ???? ??? ? ?? ?????.
??? ????: ??? ???? JVM? ??? ? ?? ??? ??? ???? ??? ?????? ???.
??? ??? ???? ???? ????? ????. ?? ????? ???? ????.Common OOM
? ???? OOM ??? ??? ????java.lang.OutOfMemoryError: PermGen space
Java7 ?? ??(??? ??) ????? ??? ??, ??, ?? ??, JIT(Just-In-Time) ????? ???? ?? ? ?? ??? ?? ??? ???? ???? ? ?????. ???? ?? ??? ??? ?????? ?? ??? ?????. ????? ?? ??? ??? ?? ?? JSP ????? ????? CgLib ?? ??? ??? ???? ?????.我們可以?? - XX:PermSize
? -XX:MaxPermSize
修改方法區(qū)大小-XX:PermSize
和 -XX:MaxPermSize
修改方法區(qū)大小
Java8 將永久代變更為元空間,報錯:java.lang.OutOfMemoryError: Metadata space,元空間內(nèi)存不足默認進行動態(tài)擴展
java.lang.StackOverflowError
虛擬機棧溢出,一般是由于程序中存在 死循環(huán)或者深度遞歸調(diào)用 造成的。如果棧大小設(shè)置過小也會出現(xiàn)溢出,可以通過 -Xss
設(shè)置棧的大小
虛擬機拋出棧溢出錯誤,可以在日志中定位到錯誤的類、方法
java.lang.OutOfMemoryError: Java heap space
Java 堆內(nèi)存溢出,溢出的原因一般由于 JVM 堆內(nèi)存設(shè)置不合理或者內(nèi)存泄漏導致
如果是內(nèi)存泄漏,可以通過工具查看泄漏對象到 GC Roots 的引用鏈。掌握了泄漏對象的類型信息以及 GC Roots 引用鏈信息,就可以精準地定位出泄漏代碼的位置
如果不存在內(nèi)存泄漏,就是內(nèi)存中的對象確實都還必須存活著,那就應該檢查虛擬機的堆參數(shù)(-Xmx 與 -Xms),查看是否可以將虛擬機的內(nèi)存調(diào)大些
小結(jié):方法區(qū)和虛擬機棧的溢出場景不在本篇過多討論,下面主要講解常見的 Java 堆空間的 OOM 排查思路
查看 JVM 內(nèi)存分布
假設(shè)我們 Java 應用 PID 為 15162,輸入命令查看 JVM 內(nèi)存分布 jmap -heap 15162
Java8 將永久代變更為元空間,報錯:java.lang.OutOfMemoryError: ????? ??,間內(nèi)存不足默認進行動態(tài)擴展
java.lang.StackOverflowError
?? 虛擬機棧溢?, 一般是由于程序中存?? 死循環(huán)或者深titude遞歸調(diào)用可以通過 -Xss 設(shè)置棧的大小????虛擬機拋出棧溢出錯誤 ,可以在日志中定位到錯誤的類、??????java.lang.OutOfMemoryError: Java ? ??????Java 堆內(nèi)存溢? , 溢出的原因一般由于 JVM 堆內(nèi)存設(shè)置不??或者內(nèi)存泄漏導致????如果是內(nèi)存泄漏,可以通過工具查看泄漏對象到 GC Roots ? ??? GC Roots???.引用鏈信息,就可以精準地密位位流泄泄漏代碼的位置????如果不存在內(nèi)存泄漏,就是內(nèi)存中的對象確實況還必須存活著,那就應該檢查虛擬機的堆參數(shù)(-Xmx 與 -Xms) ,查看是否可以將虛擬機的內(nèi)存調(diào)大些????小結(jié):方法區(qū) and 虛擬機棧的溢場景不在本篇過多討論,下面主要講解常見的 Java 堆空間的 OOM 排查思路??查看 JVM 內(nèi)存分布
??假設(shè)我們 Java 應? PID 為 15162,輸入命令查看 JVM 內(nèi)存分布jmap -heap 15162
??[xxx@xxx ~]# jmap -heap 15162 Attaching to process ID 15162, please wait... Debugger attached successfully. Server compiler detected. JVM version is 25.161-b12 using thread-local object allocation. Mark Sweep Compact GC Heap Configuration: MinHeapFreeRatio = 40 # 最小堆使用比例 MaxHeapFreeRatio = 70 # 最大堆可用比例 MaxHeapSize = 482344960 (460.0MB) # 最大堆空間大小 NewSize = 10485760 (10.0MB) # 新生代分配大小 MaxNewSize = 160759808 (153.3125MB) # 最大新生代可分配大小 OldSize = 20971520 (20.0MB) # 老年代大小 NewRatio = 2 # 新生代比例 SurvivorRatio = 8 # 新生代與 Survivor 比例 MetaspaceSize = 21807104 (20.796875MB) # 元空間大小 CompressedClassSpaceSize = 1073741824 (1024.0MB) # Compressed Class Space 空間大小限制 MaxMetaspaceSize = 17592186044415 MB # 最大元空間大小 G1HeapRegionSize = 0 (0.0MB) # G1 單個 Region 大小 Heap Usage: # 堆使用情況 New Generation (Eden + 1 Survivor Space): # 新生代 capacity = 9502720 (9.0625MB) # 新生代總?cè)萘? used = 4995320 (4.763908386230469MB) # 新生代已使用 free = 4507400 (4.298591613769531MB) # 新生代剩余容量 52.56726495150862% used # 新生代使用占比 Eden Space: capacity = 8454144 (8.0625MB) # Eden 區(qū)總?cè)萘? used = 4029752 (3.8430709838867188MB) # Eden 區(qū)已使用 free = 4424392 (4.219429016113281MB) # Eden 區(qū)剩余容量 47.665996699370154% used # Eden 區(qū)使用占比 From Space: # 其中一個 Survivor 區(qū)的內(nèi)存分布 capacity = 1048576 (1.0MB) used = 965568 (0.92083740234375MB) free = 83008 (0.07916259765625MB) 92.083740234375% used To Space: # 另一個 Survivor 區(qū)的內(nèi)存分布 capacity = 1048576 (1.0MB) used = 0 (0.0MB) free = 1048576 (1.0MB) 0.0% used tenured generation: # 老年代 capacity = 20971520 (20.0MB) used = 10611384 (10.119804382324219MB) free = 10360136 (9.880195617675781MB) 50.599021911621094% used 10730 interned Strings occupying 906232 bytes.??communication查看 JVM 內(nèi)存分配以及運行時使?情況,可以判斷內(nèi)存分配是否????
?? JVM? ???? ?? ???? ?? ?? ???? ??? ? ? ????. jmap -histo:live 15162 | ???
jmap -histo:live 15162 | more
JVM 內(nèi)存對象列表按照對象所占內(nèi)存大小排序
instances:實例數(shù) bytes:單位 byte class name:類名

明顯看到 CustomObjTest
對象實例以及占用內(nèi)存過多
可惜的是,方案存在局限性,因為它只能排查對象占用內(nèi)存過高問題
其中 "[" 代表數(shù)組,例如 "[C" 代表 Char 數(shù)組,"[B" 代表 Byte 數(shù)組。如果數(shù)組內(nèi)存占用過多,我們不知道哪些對象持有它,所以就需要 Dump 內(nèi)存進行離線分析
JVM ??? ?? ??? ??? ???? ??? ??? ?? ?????
jmap -histo:live
????: ???? ? ???: ?? ??? ??? ??: ??? ??

??? ?????CustomObjTest
?? ????? ?? ?? ???? ?????????? ????? ??? ????. ?? ?? ???? ???? ??? ??? ??? ? ?? ?????. ??? "["? ??? ?????. ?? ?? "[C"? Char ??? ???? "[B"? Byte ??? ?????. ?? ???? ?? ?? ???? ?? ??? ?? ???? ??? ? ? ???? ???? ??? ?? ???? ???? ???jmap -histo:live
? ??? ???? JVM? ?? GC? ???? ?? ??? ?????.
jmap -histo:live
? ??? ???? JVM? ?? GC? ???? ?? ??? ?????.
Dump ?? ?? Dump ??? Java ????? ??? ???. ???? ?? ??? ??,
?? ?? ??, ??? ??? ??,
?? ???? ??? ??? ?? ??
??? ?????. ????? ??? ???? ?? GC? ?? ?? ??, JVM? ??? ??? ?????????? ????, ??? ??? ?? ?? ??? ??? ? ????????JVM ?? ???? ??? ?? ????? ???????-XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=./(參數(shù)為 Dump 文件生成路徑)
當 JVM 發(fā)生 OOM 異常自動導出 Dump 文件,文件名稱默認格式:
java_pid{pid}.hprof
上面配置是在應用拋出 OOM 后自動導出 Dump,或者可以在 JVM 運行時導出 Dump 文件
jmap -dump:file=[文件路徑] [pid] # 示例 jmap -dump:file=./jvmdump.hprof 15162
在本地寫一個測試代碼,驗證下 OOM 以及分析 Dump 文件
設(shè)置 VM 參數(shù):-Xms3m -Xmx3m -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=./ public static void main(String[] args) { List<Object> oomList = Lists.newArrayList(); // 無限循環(huán)創(chuàng)建對象 while (true) { oomList.add(new Object()); } }
通過報錯信息得知,java heap space
表示 OOM 發(fā)生在堆區(qū),并生成了 hprof 二進制文件在當前文件夾下

JvisualVM 分析
Dump 分析工具有很多,相對而言 JvisualVM、JProfiler、Eclipse Mat,使用人群更多一些。下面以 JvisualVM 舉例分析 Dump 文件

列舉兩個常用的功能,第一個是能看到觸發(fā) OOM 的線程堆棧,清晰得知程序溢出的原因

第二個就是可以查看 JVM 內(nèi)存里保留大小最大的對象,可以自由選擇排查個數(shù)

點擊對象還可以跳轉(zhuǎn)具體的對象引用詳情頁面

文中 Dump 文件較為簡單,而正式環(huán)境出錯的原因五花八門,所以不對該 Dump 文件做深度解析
注意:JvisualVM 如果分析大 Dump 文件,可能會因為內(nèi)存不足打不開,需要調(diào)整默認的內(nèi)存
?? ??
????? JVM ??? ????? ???? ?? ?? ??? ?? ??? ??? ? ????.
jmap -heap
??? ??? ?? ??? ?????jmap -heap
查看是否內(nèi)存分配過小jmap -histo
查看是否有明顯的對象分配過多且沒有釋放情況jmap -dump
jmap -histo
??? ?? ??? ?? ?? ??? ?? ?? ???? ?? jmap -dump
JVM? ?? ??? ???? ???? JDK ?? MAT? ?? ??? ???? ???? ?????. ??????????? ??? ?? ? ?? ?? ???? ???. ??????? ???? ???? ???? ?? ???? ????? ????? ??? ?? ??? ???? ??? ? ????. ??????? ??? ?? ???? ???: ????? OOM? ???? ??? ??? ???? ???? ??? ?????? ?? ??? ????? ?? ?????. ??? ??? PHP ??? ????? ?? ?? ??? ?????!

? AI ??

Undress AI Tool
??? ???? ??

Undresser.AI Undress
???? ?? ??? ??? ?? AI ?? ?

AI Clothes Remover
???? ?? ???? ??? AI ?????.

Clothoff.io
AI ? ???

Video Face Swap
??? ??? AI ?? ?? ??? ???? ?? ???? ??? ?? ????!

?? ??

??? ??

???++7.3.1
???? ?? ?? ?? ???

SublimeText3 ??? ??
??? ??, ???? ?? ????.

???? 13.0.1 ???
??? PHP ?? ?? ??

???? CS6
??? ? ?? ??

SublimeText3 Mac ??
? ??? ?? ?? ?????(SublimeText3)

Spring? ??? ??? Aop? ?? ?? ??? ?? ???? ?????. Spring Boot ?? Spring Boot 2? Aop? ?? ??? ?? ??? ???? AOP?? ??? ??? ?? ??????.

OOM? ??? JVM ???? ???? ?? ????? ???? ??? ?????. ? ????? Java ????? OOM? ???? ? ??? ???? ??? ?? ???? ?????.

?OOM? ?? ????? ?? ????? ?? ? ???? ? ? ???, ? ??? ????? ??? JVM ???? ??? ?? ?????. ? ????? Java ????? OOM? ???? ? ??? ???? ??? ?? ???? ?????.

?? ??? ?? ?? ??? ?????? ????. ??? ??? ??? ??? ?? ? ????. ?? ??? ?? ???? ??? ??? ??? ???? ???? ???? ?????? ????.

?? ?? ??? ? ??? Ping An Insurance? ???? ?? ????. ??? ?? ????, ???? ??? ????? ?? ??? ???? ??? ????. ?? ??? ??? ??? ??? ? ???, ??? ????!

?? ????? Java String ???? ?? 5?? ?? ??? ???????. ?? ??? ???? ? 5?? ?? ? ? ??? ?? ??????. ? ??? ??? ??? ?? ??? ? ??? ???? ? ??? ? ????.

?? ?? ????? ???? ?? ??? C A S(?? ? ??)? ??? ???? ?? ???? ??? ???? ??? ???? ???? ?? ??? ?? ? ??? ???.

Java? ??? ??? ???? ?????. Java ???? ??? ????? ??? ?? ?? ??? ??? ???. ????? ?? ??? ? ?, ??? "???? ??" ??? ?????? Java?? ????? ???? ??? ??? ?? ??? ????? ??? ????? ??? ????.
