三、OutOfMemoryError 异常

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)。

image

通过饼图看到整个heap 11.8M 内存。system class loader加载的"java.lang.Thread"实例有内存聚集。

详细的信息:

image

栈溢出

例子:

-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 )。看看是否还可以调大一些;

从代码上检查是否存在某些对象生命周期太长,持有状态时间过长等等。

原文地址:https://www.cnblogs.com/pan2011/p/3577286.html