深入理解Java虚拟机jvm-内存溢出OOM-创建线程过多OutOfMemoryError: unable to create new native thread

创建线程过多

  • 示例
  • 虚拟机参数
  • 结果
  • 原因分析

示例

/**
 * 创建线程导致内存溢出异常
 * VM Args: -Xss2M
 * java.lang.OutOfMemoryError: unable to create new native thread
 */
public class Demo4 {
    private void dontStop() {
        while (true) {
        }
    }

    public void stackLeakByThread() {
        while (true) {
            Thread thread = new Thread(new Runnable() {
                @Override
                public void run() {
                    dontStop();
                }
            });
            thread.start();
        }
    }

    public static void main(String[] args) {
        Demo4 demo4 = new Demo4();
        demo4.stackLeakByThread();
    }
}

虚拟机参数

-Xss2M

  • -Xss2M:线程栈的大小为2M

结果

在这里插入图片描述

原因分析

每个新建线程都有2M栈内存,无限创建线程会让栈内存不断增多,最后超出虚拟机栈内存总量大小,无法创建新线程,异常

注意:操作系统分配给每个进程的内存是有限制的,譬如32位Windows的单个进程最大内存限制为2GB。HotSpot虚拟机提供了参数可以控制Java堆和方法区这两部分的内存的最大值,我们来计算一下栈的内存大小:栈的内存大小=2GB(操作系统限制)-最大堆容量-最大方法区容量-程序计数器容量(消耗内存很小,可以忽略掉)-直接内存和虚拟机进程本身耗费的内存=虚拟机栈和本地方法栈。所以,每个内存分配到的栈内存越大,可以建立的线程数量越小,建立线程时越容易把剩下的内存耗尽。

反向思考,解决该问题,可以减少堆容量,减少栈容量,通过“减少内存”的方式!

你可能感兴趣的:(jvm,java,开发语言)