【深入理解java虚拟机v3】代码清单2-6 创建线程,导致内存溢出异常

测试环境JDK1.8

给每个栈分配的内存越大,反而越容易出现OOM异常
原因:操作系统给每个进程分配的内存是有限制的,比如32位windows的单个进程的最大内存为2GB。HotSpot虚拟机提供了参数可以控制java堆和方法区这两部分的最大值,剩余的内存即为2GB减去最大堆容量,再减去最大方法区容量,程序计数器耗内存很少,可以忽略掉,如果把直接内存和虚拟机进程自身消耗的内存也去掉的话,剩余的内存就由虚拟机栈和本地方法栈来分配了。

虚拟机栈和本地方法栈内存=2G-最大堆容量-最大方法区容量-程序计数器-直接内存-虚拟机自身内存
  • 堆容量 -Xss
  • 方法区容量
    JDK1.6之前称之为老年代或永久代
    -XX:PermSize 初始值
    -XX:MaxPermSize 最大值
  • 程序计数器可以忽略;
  • 直接内存如果不调用native方法,则为0;
  • 虚拟机自身内存可以看成固定值;

那么最大线程数=(虚拟机栈+本地方法栈内存)/单个线程分配的内存

设置最大堆大小,那么根据公式,可以算出最大线程数,原例子中的大小为2M,说明允许线程数很大,需要半天才能复现,我的机器是8G64位的,个人觉得直接弄很大,假设总共为2G内存,-Xss设置为1.5G,则很快复现问题。

/**
 * VM Args:-Xss2M (这时候不妨设大些,请在32位系统下运行)
 *
 * @author zzm
 */
public class JavaVMStackOOM {

    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) throws Throwable {
        JavaVMStackOOM oom = new JavaVMStackOOM();
        oom.stackLeakByThread();
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值