文章目錄
- SOFE之stackoverflowError
- OOM之java heap space
- OOM之GC overhead limit exceeded
- OOM之Direct buffer memoery
- OOM之unable to create new native thread
- OOM之unable to create new native thread解決方案
- OOM之metaspace
SOFE之stackoverflowError
首先stackoverflowError是錯誤,不是異常。
最簡單的出發SOFE的操作,無限循環遞歸調用:
錯誤提示:
棧中壓入了太多的方法給撐爆了,棧大小根據平台有預設值,linux核心的一般是1024k,win系統預設是0。複習一下java異常的體系結構:
檢視SOFE的的繼承樹:屬于虛機機error
oom也是虛拟機錯誤。
OOM之java heap space
簡單了解:堆記憶體不夠用了。
觸發代碼如下,但是因為jvm在win平台上預設最大堆空間是記憶體的四分之一,是以很難撐爆,需要手動調小一點(10m)。
string的方法intern
錯誤效果:
直接new 位元組數組,也可以,方法很多。
OOM之GC overhead limit exceeded
大量的資源被消耗來做垃圾回收,有用的工作隻占很少的一部分。
代碼示範:不斷往list中添加string(不重複)
為了觸發效果調整jvm參數:堆大小10m,降低直接記憶體的大小為5m。運作效果:運作幾秒之後,會觸發gc overhead的異常。
可以看到爆發異常前産生了full gc,回收前後的young區大小差别不大2047—2047.出現了收不動的現象,老年區也是同樣的現象。
OOM之Direct buffer memoery
這個錯誤跟元空間有關系,元空間使用的是本地記憶體:
這個錯誤,意思是把你的直接記憶體都幹翻了!
這個故障結合2種技術出現:netty底層的nio技術。
那麼如何檢視配置設定的直接記憶體的情況呢?在rt.jar包裡面。
做一個測試,針對16g電腦,直接電腦能利用的有:
記憶體配置設定模型:
觸發Direct buffer memoery OOM異常的代碼如下,需要配置一下vm參數:
運作效果:
會發現最後一次full gc收不動了,一般做nio程式的時候經常出現這個異常。這個異常反映了你是否知道nio。
OOM之unable to create new native thread
不能建立更多新的本地線程了。高并發環境下容易觸發這個錯,因為高并發往往需要建立多線程。
因為一個系統中的線程數是有上限的。超過上限就報錯誤。
這個異常是一個非常好的案例作為回答面試官的“說一下你的記憶深刻的故障”。
觸發代碼:
linux上試運作,注意如果帶包名的java檔案,需要"-d ."這種參數。
沒有消息就是編譯成功了。運作需要帶包名:
會發現大約在1024個以内就抛出異常了。1024是理論數字,linux程序本身句柄也需要一些線程。
OOM之unable to create new native thread解決方案
會發現root使用者無上限,但是普通使用者有1024的限制。
OOM之metaspace
場景解釋:
代碼觸發: