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

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

JVM内存溢出分析-实战JVM(二)

發(fā)布時間:2024/4/13 编程问答 25 豆豆
生活随笔 收集整理的這篇文章主要介紹了 JVM内存溢出分析-实战JVM(二) 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

為什么80%的碼農(nóng)都做不了架構(gòu)師?>>> ??

JVM規(guī)范規(guī)定,除了程序計數(shù)器,虛擬機(jī)其他內(nèi)存區(qū)域均會發(fā)生內(nèi)存溢出的可能,OutOfMemoryError(OOM)

原文地址:http://www.begincode.net/blog/62? 我的網(wǎng)站,歡迎大家多提意見

本文目的:

? ? 1、通過代碼人為造成OOM,讓大家跟了解JVM運行時各區(qū)存儲的內(nèi)容。

? ? 2、通過demo讓大家實際開發(fā)過程中,能夠根據(jù)異常判斷是那個內(nèi)存區(qū)域發(fā)生的溢出,

? ? 3、讓大家了解到什么樣的代碼會產(chǎn)生OOM,開發(fā)中能夠盡量規(guī)避。

前提:

?? ? 先和大家介紹一下eclipse如何設(shè)置JVM參數(shù),Xms 最小堆內(nèi)存,Xmx最大堆內(nèi)存,

? ? ??HeapDumpOnOutOfMemoryError:發(fā)生內(nèi)存溢出時生成堆轉(zhuǎn)儲快照

一、JAVA堆內(nèi)存溢出

?代碼實例,來自<<深入理解JVM虛擬機(jī)>>

public class TestOOM {static class OOMObject{}public static void main(String[] args) {List<OOMObject> list = new ArrayList<OOMObject>();while(true){list.add(new OOMObject());}}}

運行結(jié)果如下,發(fā)生內(nèi)存溢出,在OutOfMemoryError后面會跟著 Java heap space 提示是堆內(nèi)存溢出,

同時生成?java_pid10308.hprof 文件

該文件可以用分析工具M(jìn)AT進(jìn)行分析,安裝鏈接http://www.begincode.net/blog/45?也可以用其他工具,

java.lang.OutOfMemoryError: Java heap space Dumping heap to java_pid10308.hprof ... Heap dump file created [27883798 bytes in 0.497 secs]

通過工具可以分析是內(nèi)存泄露還是內(nèi)存溢出,如果不存在泄露,那就是存在著很多對象實例無法回收,可以通過分析查看是那些對象,是否必須存活,如果必須存活在考慮適當(dāng)調(diào)整JVM堆參數(shù),如Xmx Xms等在以后的文章中會在此介紹。

二、虛擬機(jī)棧和本地方棧溢出(棧溢出)

? ? 1、虛擬機(jī)棧

? ?虛擬機(jī)棧溢出,理論上分為兩種,一種是線程請求的棧深度大于虛擬機(jī)允許的最大深度,另外一種是申請的空間不足。

? ?因為虛擬機(jī)棧記錄的是局部變量(方法變量)和函數(shù)調(diào)用棧針,則產(chǎn)生堆棧溢出一般是函數(shù)調(diào)用深度,如遞歸類或者

? ? 方法A調(diào)用方法B,方法B調(diào)用方法C這樣調(diào)用深度超過了虛擬機(jī)允許的最大深度,

? ? JVM參數(shù)設(shè)置為如下,Xss128k ?Xss是堆棧大小

-Xms20m -Xmx20m -Xss128k -XX:+HeapDumpOnOutOfMemoryError

?demo如下

public class TestOOM {static int stackIndex = 0;public void testStackOverFlow(){stackIndex++;testStackOverFlow();}public static void main(String[] args) throws Throwable {try{TestOOM oom = new TestOOM();oom.testStackOverFlow();}catch(Throwable e){System.out.println("堆棧深度(迭代次數(shù)):"+stackIndex);throw e;}} }

執(zhí)行結(jié)果,堆棧深度達(dá)到983,堆棧溢出,并會給出具體是類,方法,發(fā)生的錯誤

堆棧深度(迭代次數(shù)):983 Exception in thread "main" java.lang.StackOverflowErrorat zgwx.TestOOM.testStackOverFlow(TestOOM.java:9)at zgwx.TestOOM.testStackOverFlow(TestOOM.java:10) 相同參數(shù)情況下如果修改遞歸的方法,在方法內(nèi)創(chuàng)建幾個變量大家再看下結(jié)果。 public void testStackOverFlow(){stackIndex++;int str = 12;int str2 = 12;int str3 = 12;int str4 = 12;int str5 = 12;int str6 = 12;int str7 = 12;int str8 = 12;testStackOverFlow();}

執(zhí)行結(jié)果如下,迭代次數(shù)明顯減少,說明局部變量占用了堆棧的空間

堆棧深度(迭代次數(shù)):579 Exception in thread "main" java.lang.StackOverflowErrorat zgwx.TestOOM.testStackOverFlow(TestOOM.java:9)at zgwx.TestOOM.testStackOverFlow(TestOOM.java:18)

? ? 2、本地方法棧,本地方法棧可以通過創(chuàng)建線程的方式來實現(xiàn)溢出,因為java線程是映射到操作系統(tǒng)內(nèi)核上,所以線程會調(diào)用本地方法,造成本地方法棧的溢出

? ?本機(jī)環(huán)境沒測試出來,機(jī)器卡死了,大家可以自己試試盡量多創(chuàng)建線程,就會撐爆本地方法棧

? ?下面是找來的例子,沒見到效果,都死卡死機(jī)告終

public class Test {private void runAlways(){while(true){}}public void createThread(){while(true){Thread thread = new Thread(new Runnable(){public void run() {runAlways();}});thread.start();}}public static void main(String[] args) {Test test = new Test();test.createThread();}}

三、直接本機(jī)內(nèi)存溢出

? ? 本機(jī)內(nèi)存溢出可以無限制申請空間即可,用nio的申請緩沖區(qū)方式

public static void main(String[] args) {List list = new ArrayList();while(true){ByteBuffer byteBuffer = ByteBuffer.allocateDirect(1024*2048);list.add(byteBuffer);}}

執(zhí)行結(jié)果如下,OutOfMemoryError后面的提示,Direct buffer memory 說明了直接緩沖區(qū),

Exception in thread "main" java.lang.OutOfMemoryError: Direct buffer memoryat java.nio.Bits.reserveMemory(Bits.java:658)at java.nio.DirectByteBuffer.<init>(DirectByteBuffer.java:123)

四、方法區(qū)(永久代)溢出

? ? 方法區(qū)存儲的是加載的類信息,常量,我們就循環(huán)創(chuàng)建字符串常量,讓方法區(qū)溢出

? ? 為了盡快溢出,jvm參數(shù)設(shè)置永久代參數(shù)5M: -XX:PermSize=5m ?-XX:MaxPermSize=5m

? ? 代碼如下:

public static void main(String[] args) {List list = new ArrayList();int i = 0;while(true){list.add((String.valueOf(i++)).intern());}}

?運行結(jié)果如下:OutOfMemoryError后面提示 PermGen space ;改代碼在jdk6及以下版本能夠報出如下異常,jdk7高版本及以上部分jvm已經(jīng)逐漸開始取消永久代的原因,只會報出堆內(nèi)存異常

Exception in thread "main" java.lang.OutOfMemoryError: PermGen spaceat java.lang.String.intern(Native Method)at com.TestSocket.main(TestSocket.java:12)

轉(zhuǎn)載于:https://my.oschina.net/UpBoy/blog/514926

總結(jié)

以上是生活随笔為你收集整理的JVM内存溢出分析-实战JVM(二)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。