Java OOM异常重现代码片段收集

1. 预备知识

JVM内存结构, Java类的生命周期,Java对象声明周期

2. 代码片段

public class OOMException {
    /**
     * 堆内存溢出
     * java.lang.OutOfMemoryError: Java heap space
     * 1. 堆内存的确太小  -Xms2048M -Xmx2048M;
     * 2. 空间未及时释放;
     * */
    public static void infinateLoop(){
        long count= 0;
        try {
            List<Object> objects = new ArrayList<Object>();
            while (true) {
                count++;
                objects.add(new Object());
                System.out.println(count);
            }
        } catch(Throwable ex) {
            System.out.println(count);
            ex.printStackTrace();
        }
    }

    /**
     * 垃圾回收效率低下
     * java.lang.OutOfMemoryError: GC overhead limit exceeded
     * JDK6 新增,
     * <ul>
     *      <li>禁用该错误 -XX:-UseGCOverheadLimit<li/>
     *      <li>检查对象是否及时释放<li/>
     * </ul>
     * */
    public static void gcOverheadLimitExceeded() throws InterruptedException {
        List<String> list1 = new LinkedList<String>();
        for(int i=0;i<9999999;i++ ){
            list1.add("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"+i);
        }

        Thread.sleep(100000);

        List<String> list2 = new LinkedList<String>();
        for(int i=0;i<9999999;i++ ){
            list1.add("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"+i);
        }

        Thread.sleep(100000);

        List<String> list3 = new LinkedList<String>();
        for(int i=0;i<9999999;i++ ){
            list1.add("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"+i);
        }

        Thread.sleep(100000);
    }

    /**
     * 栈内存溢出
     * java.lang.StackOverflowError
     * -Xss 单个线程栈大小
     *
     * (1)调用层级超过最大层级
     * (2)线程栈空间太小,无法申请到足够大的栈空间 -XX:ThreadStackSize=<value>:设置线程的栈大小(字节数)(0表示默认)
     * */
    public static void stackOverFlow(AtomicLong counter){
        System.out.println(counter.incrementAndGet());
        stackOverFlow(counter);
    }

    /**
     * 永久代
     * java.lang.OutOfMemoryError: PermGen space
     * */
    public static void permGenSpace(){
        // 100 个jar包
        // 使用Class.forName("") 疯狂加载
    }

    /**
     * 分配直接内存
     * java.lang.OutOfMemoryError: Direct buffer memory
     * 操作系统没有足够多的内存时,或者进程使用的总内存超过操作系统限制时
     * -XX:MaxDirectMemorySize=1536m
     * */
    public static void directBufferMemory(){
        int size = Integer.MAX_VALUE;
        ByteBuffer buffer = ByteBuffer.allocateDirect(size);

        try {
            Thread.sleep(10000000l);
            System.out.println(buffer.capacity());
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    /**
     * 无法创建新的线程
     * java.lang.OutOfMemoryError: unable to create new native thread
     * (1) 创建线程太多
     * (2) Stack空间太小
     * */
    public static void manyThread(){
        /**
         * 抢内存和CPU导致电脑可能必须重启才能操作
         * */
        Runnable t = new Runnable(){
            public void run(){
                try {
                    Thread.sleep(1000000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        };

        for(int i = 0 ; i < 999999999;i++){
            new Thread(t).start();
            System.out.println(i);
        }
    }

    /**
     * 有人测试结果是这样的:
     * 32bit的Java VM: 0x3fffffff - 3 (= 1,073,741,820)
     * 64bit的Java VM: 0x7fffffff - 2 (= 2,147,483,645)
     *
     * java.lang.OutOfMemoryError:Requested array size exceeds VM limit
     * */
    public static void arraySizeExeccedsLimit(){
        double[] array = new double[Integer.MAX_VALUE];
        System.out.println(array.length);
    }

    /**
     * TODO 待完善
     * Out of memory:Kill process or sacrifice child
     * */
    public static void childProcessKilled(){

    }

    /**
     * TODO 待完善
     * java.lang.OutOfMemoryError:Out of swap space
     * */
    public static void outOfSwapSpace(){

    }
    
    /**
     java.lang.OutOfMemoryError: (Native method)
     通常为JNI相关C/C++函数的问题
    */
    public static void nativeMethod(){

    }

    public static void main(String[] args) throws InterruptedException {
        manyThread();
    }
}
发布了7 篇原创文章 · 获赞 0 · 访问量 2774

猜你喜欢

转载自blog.csdn.net/weilaizhixing007/article/details/81461046
今日推荐