首页 > 编程语言 > 详细

Java虚拟机内存溢出异常--《深入理解Java虚拟机》学习笔记及个人理解(三)

时间:2018-08-10 12:48:00      阅读:113      评论:0      收藏:0      [点我收藏+]

Java虚拟机内存溢出异常--《深入理解Java虚拟机》学习笔记及个人理解(三)

1. 堆内存溢出

不断地创建对象, 而且保证创建的这些对象不会被回收即可(让GC Root可达).

/**
 * 堆内存溢出demo
 * VM Options: -Xms6m -Xmx6m
 */
public class HeapOOM {
    static class OOMObejct {

    }

    public static void main(String[] args) {
        List<OOMObejct> list = new ArrayList<>();
        while (true) {
            list.add(new OOMObejct());
        }
    }
}

 会内存溢出, 输出结果如下:

技术分享图片

如果是用下面这段代码的话, 是不会内存溢出的. 因为有GC. 每次new 的 Object在下次for循环中都退出了作用域, 虚拟机栈不再持有对象的引用. 所以会被GC掉. 不会溢出.

/**
 * 堆内存溢出demo
 * VM Options: -Xms6m -Xmx6m
 */
public class HeapOOM {
    static class OOMObejct {

    }

    public static void main(String[] args) {
        while (true) {
            new OOMObejct();
        }
    }
}

 visualVM的堆内存图如下:

技术分享图片

2. 虚拟机栈溢出

/**
 * 栈内存溢出demo
 * VM Options: -Xms6m -Xmx6m
 */
public class StackOverflow {
    private int stackDepth;

    private void stackLeak() {
        stackDepth++;
        stackLeak();
    }

    public static void main(String[] args) {
        StackOverflow oom = new StackOverflow();
        try {
            oom.stackLeak();
        } catch (Throwable e) {
            System.out.println(oom.stackDepth);
            System.err.println(e.toString());
        }
    }
}

 输出结果如下(下面部分结果可能根据机器环境不同而不同):  

技术分享图片

3. 创建线程导致的内存溢出

import java.util.concurrent.atomic.AtomicInteger;

/**
 * 创建线程导致的内存溢出demo
 * VM Options: -Xms6m -Xmx6m
 */
public class CreateThreadOOM {
    static AtomicInteger counter = new AtomicInteger(0);

    public static void main(String[] args) {
        while (true) {
            new Thread(() -> {
                try {
                    System.out.println(counter.incrementAndGet());
                    Thread.sleep(Integer.MAX_VALUE);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }).start();
        }
    }
}

 输出结果如下(下面部分结果可能根据机器环境不同而不同): 技术分享图片

4. 直接内存溢出

这段代码我这里没有运行出书上的效果...

书上的意思应该是, 设定了直接内存大小最大为10M后, 继续申请的话, 就会报异常..

在我电脑上, 虽然也设置了MaxDirectMemorySize=10m , 但是这玩意硬生生地申请了10G的虚拟内存也没停下, 最后被操作系统强制停止了.....(运行了几次电脑都快没电了)

import sun.misc.Unsafe;

import java.lang.reflect.Field;

/**
 * VM Options: -Xms6m -Xmx6m -XX:MaxDirectMemorySize=10m
 */
public class DirectMemoryOOM {
    private static final int _1MB = 1024 * 1014;

    public static void main(String[] args) throws IllegalAccessException, InterruptedException {
        Field unsafeFile = Unsafe.class.getDeclaredFields()[0];
        unsafeFile.setAccessible(true);
        Unsafe unsafe = (Unsafe) unsafeFile.get(null);
        while (true) {
            unsafe.allocateMemory(_1MB);
            Thread.sleep(10);
        }
    }
}

  

Java虚拟机内存溢出异常--《深入理解Java虚拟机》学习笔记及个人理解(三)

原文:https://www.cnblogs.com/noKing/p/9452710.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!