java - outofmemory

來源:趣味經驗館 5.79K

<link rel="stylesheet" href="https://js.how234.com/third-party/SyntaxHighlighter/shCoreDefault.css" type="text/css" /><script type="text/javascript" src="https://js.how234.com/third-party/SyntaxHighlighter/shCore.js"></script><script type="text/javascript"> SyntaxHighlighter.all(); </script>

java outofmemory是什麼,讓我們一起了解一下?

out of memory(內存溢出)是一個程序員常見的錯誤類型,通常是開啟應用程序過多所導致。一般是由於電腦內存不足,配置過低,電腦開啟的應用程序過多,導致內存不足或者遊戲客户端的問題。

Java中OutOfMemoryError(內存溢出)出現的情況和解決辦法是什麼?

第一種OutOfMemoryError: PermGenspace。
發生這種問題的原意是程序中使用了大量的jar或class,使java虛擬機裝載類的空間不夠,與PermanentGeneration space有關。解決這類問題有以下兩種辦法: 
1、增加java虛擬機中的XX:PermSize和XX:MaxPermSize參數的大小,其中XX:PermSize是初始永久保存區域大小,XX:MaxPermSize是最大永久保存區域大小。如針對tomcat6.0,在catalina.sh或catalina.bat文件中一系列環境變量名説明結束處(大約在70行左右) 增加一行: 
JAVA_OPTS=" -XX:PermSize=64M -XX:MaxPermSize=128m" 。
如果是windows服務器還可以在系統環境變量中設置。感覺用tomcat發佈sprint+struts+hibernate架構的程序時很容易發生這種內存溢出錯誤。
2、清理應用程序中web-inf/lib下的jar,如果tomcat部署了多個應用,很多應用都使用了相同的jar,可以將共同的jar移到tomcat共同的lib下,減少類的重複加載。這種方法是網上部分人推薦的,我沒試過,但感覺減少不了太大的空間,最靠譜的還是第一種方法。 

java outofmemory

第二種OutOfMemoryError: Java heap space 。
發生這種問題的原因是java虛擬機創建的對象太多,在進行垃圾回收之間,虛擬機分配的到堆內存空間已經用滿了,與Heapspace有關。解決這類問題有兩種思路: 
1、檢查程序,看是否有無窮迴圈或不必要地重複創建大量對象。找到原因後,修改程序和算法。 
寫一個使用K-Means文本聚類算法對幾萬條文本記錄(每條記錄的特徵向量大約10來個)進行文本聚類時,由於程序細節上有問題,就導致了Javaheap space的內存溢出問題,後來通過修改程序得到了解決。 
2、增加Java虛擬機中Xms(初始堆大小)和Xmx(最大堆大小)參數的大小。如:set JAVA_OPTS= -Xms256m-Xmx1024m。

實戰操作,本機內存溢出代碼如下:

package DirectMemory;import sun.misc.Unsafe;import java.lang.reflect.Field;/** * VM Args: -Xmx20M -XX:MaxDirectMemorySize=10M * DirectByteBuffer分配內存也會拋出內存溢出異常,但它拋出異常時沒有真正向系統申請分配內存,而是通過計算得知內存 * 無法分配,於是手動拋出異常。有點類似操作系統的銀行家算法(避免死鎖) */public class DirectMemoryOOM {    private static final int _1MB = 1024*1024;    public static void main(String[] args) throws IllegalAccessException {        Field unsafeField = Unsafe.class.getDeclaredFields()[0];        //獲取類中第一個變量        unsafeField.setAccessible(true);                               //設置是否可反射訪問private變量        Unsafe unsafe = (Unsafe) unsafeField.get(null);             //獲取靜態對象        while (true){            unsafe.allocateMemory(_1MB);                            //申請分配內存        }    }}

熱門標籤