JVM 常见异常及内存诊断
棧內存溢出
棧內存大小設置:-Xss size 默認除了window以外的所有操作系統默認情況大小為 1MB,window 的默認大小依賴于虛擬機內存。
棧幀過多導致棧內存溢出
下述示例代碼,由于遞歸深度沒有限制且沒有設置出口,每次方法的調用都會產生一個棧幀導致了創建的棧幀過多,而導致內存溢出(StackOverflowError)。
示例代碼:
運行結果:
棧幀過大導致棧內存溢出
示例代碼:
運行結果:
如下所示部門依賴員工集合,員工依賴于部門,如此一來,由于循環引用使得棧幀過大從而導致棧內存的溢出。
因此我們的解決思路是:打破循環引用來解決,如下所示(當然這只是針對當前實例場景的解決方式,其主要目的是提供一種解決問題的思路)
堆內存溢出
堆內存大小設置參數:-Xmx
雖然“堆”是垃圾回收的主要管理區域,但垃圾回收主要是針對已經無用的對象的,如果被引用的對象而且不斷的產生新對象而且一直被使用時,垃圾回收器是不會處理被使用的對象的。如果不斷產生新對象最終超出了堆的內存大小,則會導致堆內存的溢出。
示例代碼:
默認情況下下述代碼一般不會出現堆內存溢出情況
把jvm的堆內存上限大小設置成8MB,然后再運行程序
運行結果:
說明:一般出現該情況我們是可以解決的,一方面是確實是因為內存不夠的,我們適當的調整內存大小,另一方面就是程序邏輯本身有問題,如下圖邏輯,這是一個死循環,字符串通過不斷的添加,沒有終止的時候,不管設置多大的內存都會最終撐爆最大的內存限定,從而導致了內存的溢出,以異常退出程序收場。
?
?
堆內存診斷:
jps: 查看當前系統中有那些java進程
.....\demos\jvmbase>jps
28036
15180 Jps
6140 Demo1
jmap 工具: 查看堆內存占用情況(瞬時的)
jmap? -heap 進程id
下述是該命令呈現的部分內容,下述是堆內存某個瞬間的使用情況 如下:
?
jconsole 工具: 圖形界面的,內存java性能分析器,多功能的監測工具,可以連續監測
方法區內存溢出
代碼示例(基于jdk1.8):
上述代碼運行,在沒有限定元空間大小的時候一般很難出現方法區內存溢出。
下面通過限定元空間的大小為8M,然后重新運行程序
通過限定元空間的大小,這時候會發現程序會拋出方法區的內存溢出(也就是元空間導致的內存溢出)
?
代碼示例(基于jdk1.6): 程序邏輯整體與上述jdk1.8一致,修改jdk版本為1.6:
默認情況下不設置方法區的內存大小一般也不會輕易出現問題,下面我們同意通過修改內存大小進行試驗
下面通過限定方法區(永久代)的大小為8M,然后重新運行程序
通過限定方法區(永久代)的大小,這時候會發現程序會拋出方法區的內存溢出(也就是永久代導致的內存溢出)
?
總結
以上是生活随笔為你收集整理的JVM 常见异常及内存诊断的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 2022-2028年中国汽轮发电机行业市
- 下一篇: 2022-2028年中国汽车制动器行业投