2025-04-23

內存溢出(OOM)的原因

–在JVM中,有哪些內存區間?

永久區

Java棧

直接內存

–堆溢出

public static void main(String args[]){

    ArrayList list=new ArrayList();

    for(int i=0;i<1024;i++){

        list.add(new byte[1024*1024]);

    }

}

占用大量堆空間,直接溢出

 

Exception in thread "main" java.lang.OutOfMemoryError: Java heap space

at geym.jvm.ch8.oom.SimpleHeapOOM.main(SimpleHeapOOM.java:14)

 

解決方法:增大堆空間,及時釋放內存

–永久區

生成大量的類

public static void main(String[] args) {

    for(int i=0;i<100000;i++){

        CglibBean bean = new CglibBean("geym.jvm.ch3.perm.bean"+i,new HashMap());

    }

}

Caused by: java.lang.OutOfMemoryError: PermGen space

解決方法:增大Perm區,允許Class回收

 

–Java棧溢出

n這裡的棧溢出指,在創建線程的時候,需要為線程分配棧空間,這個棧空間是向操作系統請求的,如果操作系統無法給出足夠的空間,就會拋出OOM

示例:

設置JVM參數 :-Xmx1g -Xss1m 內存空間最大值為1G,線程棧大小為1M

public static class SleepThread implements Runnable{

    public void run(){

        try {

            Thread.sleep(10000000);

        } catch (InterruptedException e) {

            e.printStackTrace();

        }

    }

}

public static void main(String args[]){

    for(int i=0;i<1000;i++){

        new Thread(new SleepThread(),"Thread"+i).start();

        System.out.println("Thread"+i+" created");

    }

}

 

運行結果:

Exception in thread "main" java.lang.OutOfMemoryError:

unable to create new native thread

 

解決方法:減少堆內存,減少線程棧大小

 

使用Visual VM分析堆

 

–java自帶的多功能分析工具,可以用來分析堆Dump

類的柱狀圖 ,顯示對象數量,總大小等:

從類試圖切換到實例試圖,顯示所有的實例:

使用OQL查詢:

返回引用瞭(0,0)這個點的所有對象

 

Tomcat OOM分析案例

Tomcat 在接收大量請求時發生OOM,獲取堆Dump档案,進行分析。

如果是session過多引起OOM

–OOM由於保存session過多引起,可以考慮增加堆大小

–如果應用允許,縮短session的過期時間,使得session可以及時過期,並回收

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *