有興趣狗了一下找到一篇教怎麼偵測跟處理的文章,
https://blogs.oracle.com/jrockit/entry/repost_tips_and_tricks_for_dealing_with_a_fragmented_java_heap
縮:
![]()
簡單摘要如下
推薦偵測工具:
JRockit Mission Control
Memory Leak Detector
1. Increase the heap size
這...有錢好辦事 @@?
2. Use a generational GC
用不同的 GC 策略,用參數 -Xgc:gencon 或 -Xgc:genpar
3. Tune compaction parameters
調大 compaction ratio (e.g. -XXcompactratio=10) 早點做 defragment
4. Don't allocate memory
太神妙了,光看這句會讓人覺得是在說什麼屁話 0rz
請參考另一篇文章。
https://blogs.oracle.com/hirt/entry/unorthodox_uses_of_the_memory
縮:
![]()
5. Avoid allocating large objects
少用 Array 等大型物件,(例如 ArrayList 可能改用 LinkedList?),
避免巨大的 String 也就是 char array (也改用 char linked list?)。
6. Allocate objects with similar lifespan in chunks
將一個操作要用到的資料在操作結束前都維持住不清,
讓它們之後可以一口氣同時被清掉,減少小的空洞。
※ 引述《AmosYang (Zzz...)》之銘言:
: ※ 引述《PsMonkey (痞子軍團團長)》之銘言:
: : 在花了一天對付另一個 [Heisenbug]:每當我快抓到原因,它就會變了樣;
: 閒聊瞎扯一下 :>
: 前幾個月正好處理過一個類似的情形: 一個 multithreaded 的 .NET 程式不定時的
: 炸 OOM exception
: 對付陳宮,只能用箭;對付 Heisenbug, 除了 process dump analysis 外
: 大概沒什麼好辦法
: 參考
: * http://blogs.msdn.com/b/dotnet/archive/2009/10/15/automatically-capturing-a-dump-when-a-process-crashes.aspx
: * http://blogs.msdn.com/b/pranavwagh/archive/2009/06/09/how-to-take-the-dump-for-a-process-which-crashes-randomly.aspx
: * http://technet.microsoft.com/en-us/sysinternals/dd996900.aspx
: * http://stackoverflow.com/questions/1134048/generating-net-crash-dumps-automatically
: * google jvm crash dump
: 通常來說, OOM 算是好解的問題,因為 OOM 多半來自 memory leak + loop
: 是故 heap 裡多半會散佈著大量相似的物件, 只要能辨認這些物件
: 通常反推回程式碼裡的問題點就沒那麼難
: 然而,有另一型的 OOM, 很久之前有稍微提過, 是屬於 architectural 的問題,
: 就很難解 :( 因為 OutOfMemory 有時指的不是「記憶體的量不夠」
: 而是「沒有連續夠大塊的記憶體」
: 該案例裡,就是大量地創造、釋放大型物件 ( 大型物件會取在 .NET gen 2 heap ) 上
: 使得 gen 2 heap 的「連續可用空間」變得支離破碎,
: 而「可用空間總量」看起來還剩很多
: 打個比方,就像一立方公尺的木條跟一立方公尺的木屑都是一立方公尺的木料
: 但後者沒辦法拿來蓋房子; 在這種情形下,不管是 .NET 還是 Java,
: 都只會炸 OOM, 不知道為什麼不能設計成改炸 OutOfContinuousMemory 這種的...
: 最近幾期的 MSDN 雜誌裡提到最新的 .NET GC 應該可以避免 fragmentation 發生
: 不知道最新的 Java 8 在這方面有沒有相對應的改進
: 這種 OOM 就很難解…最快的解法就是裝傻... :D
: 總結: 寫 server 程式時,若能把該平台上的 debug 工具摸熟,常會有意想不到的妙用