JAVA 堆溢出
例子:
VM options 设置为:-Xms20m -Xmx20m -XX:+HeapDumpOnOutOfMemoryError
package com.panpan.web.controller; import java.util.ArrayList; import java.util.List; /** * 内存溢出 * Created with IntelliJ IDEA. * User: hp * Date: 14-3-1 * Time: 下午10:42 * To change this template use File | Settings | File Templates. */ public class TestMemory { private static class ArrayMemory { } public static void main(String[] args) { List<ArrayMemory> arrayMemories = new ArrayList<ArrayMemory>(); while (true) { arrayMemories.add(new ArrayMemory()); } } }
控制台输出如下信息:
java.lang.OutOfMemoryError: Java heap space Dumping heap to java_pid392.hprof ... Heap dump file created [22120833 bytes in 0.248 secs] Exception in thread "main" java.lang.OutOfMemoryError: Java heap space at java.util.Arrays.copyOf(Arrays.java:2760) at java.util.Arrays.copyOf(Arrays.java:2734) at java.util.ArrayList.ensureCapacity(ArrayList.java:167) at java.util.ArrayList.add(ArrayList.java:351) at com.panpan.web.controller.TestMemory.main(TestMemory.java:13)
java_pid392.hprof 是一个 heap dump 文件,通过 MemoryAnalyzer 可以分析对象的情况(下载猛戳:http://www.eclipse.org/mat/downloads.php)。
通过饼图看到整个heap 11.8M 内存。system class loader加载的"java.lang.Thread"实例有内存聚集。
详细的信息:
栈溢出
例子:
-vm options 设置为:-Xss128k
package com.panpan.web.controller; /** * 栈溢出实例 * Created with IntelliJ IDEA. * User: hp * Date: 14-3-2 * Time: 下午8:20 */ public class TestStack { private int stack = 1; public static void main(String[] args) throws Exception { TestStack testStack = new TestStack(); try { testStack.testPuls(); } catch (Exception e) { System.out.println("stack 的长度 为 :" + testStack.stack); throw e; } } private void testPuls() { stack++; testPuls(); } }
控制台如下:
Exception in thread "main" java.lang.StackOverflowError at com.panpan.web.controller.TestStack.testPuls(TestStack.java:25) ...(此处省略N行)
运行时常量溢出
例子:
向常量池中不断的添加内容,可以使用String.intern() 这个native 方法。它的作用是:如果池中已经包含了一个String对象字符串。则返回这个字符串。否则将这个字符串添加到常量池中。
-vm options 设置为:-XX:PermSize=10M -XX:MaxPermSize=10M
package com.panpan.web.controller; import java.util.ArrayList; import java.util.List; /** 常量池溢出 * Created with IntelliJ IDEA. * User: hp * Date: 14-3-2 * Time: 下午8:55 */ public class TestConstantError { public static void main(String[] args) { List<String> stringList = new ArrayList<String>(); int i = 0 ; while (true) { stringList.add(String.valueOf(i++).intern()); } } }
控制台
Exception in thread "main" java.lang.OutOfMemoryError: PermGen space
at java.lang.String.intern(Native Method)
at com.panpan.web.controller.TestConstantError.main(TestConstantError.java:18)
虽然java有垃圾回收机制,但是内存溢出离我们并不遥远。
如果出现内存泄露,那就应该坚持虚拟机的参数设置(-Xms 和 –Xmx )。看看是否还可以调大一些;
从代码上检查是否存在某些对象生命周期太长,持有状态时间过长等等。