內存溢出(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可以及時過期,並回收