中文字幕日韩精品一区二区免费_精品一区二区三区国产精品无卡在_国精品无码专区一区二区三区_国产αv三级中文在线

Java中的內(nèi)存溢出問(wèn)題怎么解決

本篇內(nèi)容主要講解“Java中的內(nèi)存溢出問(wèn)題怎么解決”,感興趣的朋友不妨來(lái)看看。本文介紹的方法操作簡(jiǎn)單快捷,實(shí)用性強(qiáng)。下面就讓小編來(lái)帶大家學(xué)習(xí)“Java中的內(nèi)存溢出問(wèn)題怎么解決”吧!

北戴河網(wǎng)站建設(shè)公司創(chuàng)新互聯(lián)公司,北戴河網(wǎng)站設(shè)計(jì)制作,有大型網(wǎng)站制作公司豐富經(jīng)驗(yàn)。已為北戴河上1000+提供企業(yè)網(wǎng)站建設(shè)服務(wù)。企業(yè)網(wǎng)站搭建\成都外貿(mào)網(wǎng)站制作要多少錢(qián),請(qǐng)找那個(gè)售后服務(wù)好的北戴河做網(wǎng)站的公司定做!

一、內(nèi)存溢出原因

內(nèi)存溢出就是內(nèi)存不夠,引起內(nèi)存溢出的原因有很多種,常見(jiàn)的有以下幾種:

1、內(nèi)存中加載的數(shù)據(jù)量過(guò)于龐大,如一次從數(shù)據(jù)庫(kù)取出過(guò)多數(shù)據(jù);

2、集合類(lèi)中有對(duì)對(duì)象的引用,使用完后未清空,使得JVM不能回收;

3、代碼中存在死循環(huán)或循環(huán)產(chǎn)生過(guò)多重復(fù)的對(duì)象實(shí)體;

4、使用的第三方軟件中的BUG;

5、啟動(dòng)參數(shù)內(nèi)存值設(shè)定的過(guò)小;

當(dāng)然實(shí)際情況中內(nèi)存溢出的原因就太多了。下面我們就對(duì)這些原因分類(lèi)一下:

以上的圖是基于java7來(lái)敘述的,從上面這張圖我們能夠得到如下信息:java虛擬機(jī)把內(nèi)存分為5個(gè)模塊。

(1)程序計(jì)數(shù)器:程序計(jì)數(shù)器是線(xiàn)程私有的,主要的作用是通過(guò)改變這個(gè)計(jì)數(shù)器的值來(lái)選取下一條需要執(zhí)行的字節(jié)碼指令。既然每個(gè)線(xiàn)程都有一個(gè),那么這些線(xiàn)程的計(jì)數(shù)器是互不影響的。也不會(huì)拋出任何異常。

(2)虛擬機(jī)棧和本地方法棧:虛擬機(jī)棧描述的是java方法執(zhí)行的內(nèi)存模型,每個(gè)方法在執(zhí)行的時(shí)候都會(huì)創(chuàng)建一個(gè)棧幀用于存儲(chǔ)局部變量表、操作數(shù)棧、動(dòng)態(tài)連接、方法出口等信息。本地方法棧與虛擬機(jī)棧的區(qū)別是,虛擬機(jī)棧為虛擬機(jī)執(zhí)行java方法服務(wù),而本地方法棧則為虛擬機(jī)提供native方法服務(wù)。

在單線(xiàn)程的操作中,無(wú)論是由于棧幀太大,還是虛擬機(jī)棧空間太小,當(dāng)??臻g無(wú)法分配時(shí),虛擬機(jī)拋出的都是StackOverflowError異常,而不會(huì)得到OutOfMemoryError異常。而在多線(xiàn)程環(huán)境下,則會(huì)拋出OutOfMemoryError異常。

(3)java堆和方法區(qū):java堆區(qū)主要存放對(duì)象實(shí)例和數(shù)組等,方法區(qū)保存類(lèi)信息、常量、靜態(tài)變量等等。運(yùn)行時(shí)常量池也是方法區(qū)的一部分。這兩塊區(qū)域是線(xiàn)程共享的區(qū)域,只會(huì)拋出OutOfMemoryError。

不知道各位在B站看見(jiàn)過(guò)那個(gè)面試經(jīng)典場(chǎng)景沒(méi),在回答java的內(nèi)存運(yùn)行數(shù)據(jù)區(qū)結(jié)構(gòu)時(shí),以上的功能作用是一方面,如果回答時(shí)把內(nèi)存溢出問(wèn)題添加上是一個(gè)極大的加分項(xiàng)。

二、內(nèi)存溢出實(shí)例

1、堆溢出

既然堆是存放實(shí)例對(duì)象的,那我們就無(wú)線(xiàn)創(chuàng)建實(shí)例對(duì)象。這樣堆區(qū)遲早會(huì)滿(mǎn)。

public class HeapOOM {     static class User {}  public static void main(String[] args) {    List<User> list = new ArrayList<User>();          while (true) {              list.add(new User());       }  } } /*Exception in thread "main" java.lang.OutOfMemoryError:  GC overhead limit exceeded  at com.fdd.test.HeapOOM.main(HeapOOM.java:11)*/

因?yàn)槲姨崆霸O(shè)置了堆區(qū)內(nèi)存,所以無(wú)限創(chuàng)建就會(huì)拋出異常。

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

Java虛擬機(jī)規(guī)范中描述了兩種異常:

  • 如果線(xiàn)程請(qǐng)求的棧深度大于虛擬機(jī)鎖允許的最大深度,將拋出StackOverflowError異常。

  • 如果虛擬機(jī)在擴(kuò)展棧時(shí)無(wú)法申請(qǐng)到足夠的內(nèi)存空間,則拋出OutOfMemoryError異常。

第一種我們只需要使用方法遞歸調(diào)用即可模擬:

public class StackOutOfMemoryError {     public static void main(String[] args) {               test();     }     private static void go() {         System.out.println("StackOverflowError異常");         test();     } } /*Exception in thread "main" java.lang.StackOverflowError  at sun.nio.cs.ext.DoubleByte$Encoder.encodeLoop(DoubleByte.java:617)  at java.nio.charset.CharsetEncoder.encode(CharsetEncoder.java:579)  at sun.nio.cs.StreamEncoder.implWrite(StreamEncoder.java:271)  at sun.nio.cs.StreamEncoder.write(StreamEncoder.java:125)  at java.io.OutputStreamWriter.write(OutputStreamWriter.java:207)  at java.io.BufferedWriter.flushBuffer(BufferedWriter.java:129)  at java.io.PrintStream.write(PrintStream.java:526)  at java.io.PrintStream.print(PrintStream.java:597)  at java.io.PrintStream.println(PrintStream.java:736)  at com.fdd.test.StackOutOfMemoryError.go(StackOutOfMemoryError.java:11)  at com.fdd.test.StackOutOfMemoryError.go(StackOutOfMemoryError.java:13)*/

第二種也可以遞歸調(diào)用模擬,,但是使用的是類(lèi)直接調(diào)用。

public class JavaVMStackSOF {     private int stackLength = 1;     public void stackLeak() {         stackLength++;         stackLeak();     }  public static void main(String[] args) {         JavaVMStackSOF oom = new JavaVMStackSOF();         oom.stackLeak();     } } /*Exception in thread "main" java.lang.StackOverflowError    at com.lindaxuan.outofmemory.JavaVMStackSOF.stackLeak(JavaVMStackSOF.java:18)    at com.lindaxuan.outofmemory.JavaVMStackSOF.stackLeak(JavaVMStackSOF.java:19)    at com.lindaxuan.outofmemory.JavaVMStackSOF.stackLeak(JavaVMStackSOF.java:19)    at com.lindaxuan.outofmemory.JavaVMStackSOF.stackLeak(JavaVMStackSOF.java:19)    at com.lindaxuan.outofmemory.JavaVMStackSOF.stackLeak(JavaVMStackSOF.java:19)    at com.lindaxuan.outofmemory.JavaVMStackSOF.stackLeak(JavaVMStackSOF.java:19)    at com.lindaxuan.outofmemory.JavaVMStackSOF.stackLeak(JavaVMStackSOF.java:19)    at com.lindaxuan.outofmemory.JavaVMStackSOF.stackLeak(JavaVMStackSOF.java:19)    at com.lindaxuan.outofmemory.JavaVMStackSOF.stackLeak(JavaVMStackSOF.java:19)    ... */

3、方法區(qū)和運(yùn)行時(shí)常量池溢出

public class JavaMethodAreaOOM {     public static void main(String[] args) {         while (true) {             Enhancer enhancer = new Enhancer();             enhancer.setSuperclass(User.class);             enhancer.setUseCache(false);             enhancer.setCallback(new MethodInterceptor() {                 public Object intercept(Object obj, Method method,                       Object[] args, MethodProxy proxy) throws Throwable {                     return proxy.invokeSuper(obj, args);                 }             });             enhancer.create();         }     }     static class User {} } /*Exception in thread "main"  Exception: java.lang.OutOfMemoryError thrown   from the UncaughtExceptionHandler in thread "main" */

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

DirectMemory容量可通過(guò)-XX: MaxDirectMemorySize指定,如果不指定,則默認(rèn)與Java堆最大值  (-Xmx指定)一樣。

public class DirectMemoryOOM {     private static final int _1MB = 1024 * 1024;     public static void main(String[] args) throws Exception {         Field unsafeField = Unsafe.class.getDeclaredFields()[0];         unsafeField.setAccessible(true);         Unsafe unsafe = (Unsafe) unsafeField.get(null);         while (true) {             unsafe.allocateMemory(_1MB);         }     } }

上面介紹了幾個(gè)實(shí)例,那遇到這種問(wèn)題如何排查呢?

三、內(nèi)存溢出排查

排查其實(shí)最主要的就是檢查代碼,而且內(nèi)存溢出往往都是代碼的問(wèn)題。當(dāng)然一下幾點(diǎn)都是需要注意的:

(1)內(nèi)存中加載的數(shù)據(jù)量過(guò)于龐大,如一次從數(shù)據(jù)庫(kù)取出過(guò)多數(shù)據(jù);

(2)集合類(lèi)中有對(duì)對(duì)象的引用,使用完后未清空,使得JVM不能回收;

(3)代碼中存在死循環(huán)或循環(huán)產(chǎn)生過(guò)多重復(fù)的對(duì)象實(shí)體;

(4)使用的第三方軟件中的BUG;

(5)啟動(dòng)參數(shù)內(nèi)存值設(shè)定的過(guò)小;

最后就是解決了。

第一步,修改JVM啟動(dòng)參數(shù),直接增加內(nèi)存。

第二步,檢查錯(cuò)誤日志

第三步,對(duì)代碼進(jìn)行走查和分析,找出可能發(fā)生內(nèi)存溢出的位置。

到此,相信大家對(duì)“Java中的內(nèi)存溢出問(wèn)題怎么解決”有了更深的了解,不妨來(lái)實(shí)際操作一番吧!這里是創(chuàng)新互聯(lián)網(wǎng)站,更多相關(guān)內(nèi)容可以進(jìn)入相關(guān)頻道進(jìn)行查詢(xún),關(guān)注我們,繼續(xù)學(xué)習(xí)!

名稱(chēng)欄目:Java中的內(nèi)存溢出問(wèn)題怎么解決
路徑分享:http://www.rwnh.cn/article38/gcgipp.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供網(wǎng)頁(yè)設(shè)計(jì)公司、服務(wù)器托管、商城網(wǎng)站、靜態(tài)網(wǎng)站、電子商務(wù)網(wǎng)站建設(shè)

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶(hù)投稿、用戶(hù)轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀(guān)點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話(huà):028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)

成都app開(kāi)發(fā)公司
阜平县| 宝坻区| 南乐县| 金沙县| 蛟河市| 隆安县| 静安区| 滕州市| 桓台县| 海兴县| 上高县| 扶余县| 建湖县| 乌兰县| 民和| 黔江区| 绥江县| 闽侯县| 错那县| 汝阳县| 海淀区| 澄迈县| 万荣县| 玉溪市| 敖汉旗| 宜良县| 淳安县| 临桂县| 稻城县| 揭西县| 象山县| 张家川| 仲巴县| 阳泉市| 湾仔区| 吴堡县| 广宗县| 泽库县| 贵阳市| 临武县| 三河市|