两种类型的Out of Memory

  1. java.lang.OutOfMemoryError: Java heap space error

    当JVM尝试在堆中分配对象,堆中空间不足时抛出。一般通过设定JAVA启动参数-Xmx最小可用内存解决。
  2. java.lang.OutOfMemoryError: Unable to create new native thread

    当JVM向OS申请创建线程,而OS不能分配一个本地线程时抛出。

了解系统参数

系统级最大进程ID

$ sysctl -a | grep kernel.pid_max
kernel.pid_max = 32768
# 输出结果表示当前系统允许的最大进程数为32768 $ cat /proc/sys/kernel/pid_max
# 命令功用与上述同样 $ echo 200000 > /proc/sys/kernel/pid_max
# 修改系统级最大进程数为200000,可通过sysctl查看修改

系统级最大线程数

# /proc/sys/kernel/threads-max 限制了系统级最大线程数
$ echo 120000 > /proc/sys/kernel/threads-max
# 修改系统级最大线程数为120000,可通过sysctl查看修改
# Linux没有每个进程单独的最大线程数限制

ulimit 检查OS是否允许用户申请足够多的进程(含线程)

$ ulimit -a
core file size (blocks, -c) 0
data seg size (kbytes, -d) unlimited
scheduling priority (-e) 0
file size (blocks, -f) unlimited
pending signals (-i) 515005
max locked memory (kbytes, -l) 64
max memory size (kbytes, -m) unlimited
open files (-n) 4096
pipe size (512 bytes, -p) 8
POSIX message queues (bytes, -q) 819200
real-time priority (-r) 0
stack size (kbytes, -s) 10240
cpu time (seconds, -t) unlimited
max user processes (-u) 1024
virtual memory (kbytes, -v) unlimited
file locks (-x) unlimited
# 通过ulimit -u,可见用户默认的最大进程(含线程)数是1024
# 通过ulimit -s,可见进程默认的最大栈大小是10M $ ulimit -u 32000
# 更改用户默认的最大进程(含线程)数为32000

如何验证 ulimit 中的资源限制?如何查看当前使用量?

Modify 'Soft Limit' of 'Max processes'

Linux对最大线程数的硬控制

number of threads = total virtual memory / (stack size10241024)

从上可知,最大线程数的增加可以通过增加虚拟内存或减少线程栈大小两种手段。

但是,减少线程栈大小可能会导致栈溢出的异常。

$ ulimit -v newValue
# 更改进程默认的虚拟内存大小 $ ulimit -s newValue
# 更改进程默认的栈大小

max_map_count 间接影响线程数量

max_map_count文件包含限制一个进程可以拥有的VMA(虚拟内存区域)的数量。默认值是65536。

虚拟内存区域是一个连续的虚拟地址空间区域。在进程的生命周期中,每当程序尝试在内存中映射文件,链接到共享内存段,或者分配堆空间的时候,这些区域将被创建。

调优这个值将限制进程可拥有VMA的数量。限制一个进程拥有VMA的总数可能导致应用程序出错,因为当进程达到了VMA上限但又只能释放少量的内存给其他的内核进程使用时,操作系统会抛出内存不足的错误。

如果你的操作系统在NORMAL区域仅占用少量的内存,那么调低这个值可以帮助释放内存给内核用。

因值过低抛错在JVM中可能会呈现Java.lang.OutOfMemoryError: Map failed。详情参见max_map_count超出导致的OOM

$ echo 'vm.max_map_count=655360' >> /etc/sysctl.conf
# rocketmq系统参数配置了默认值的10倍 $ echo 600000 > /proc/sys/vm/max_map_count
# 更改VMA映射数量为600000,可通过sysctl查看修改

参数之间的关联

线程本质上是进程,显著区别在于线程运行在共享内存空间,而进程运行在独立内存空间

/proc/sys/kernel/pid_max 决定的进程数是运行于独立内存空间的进程

/proc/sys/kernel/threads-max 决定的线程数是运行于共享内存空间的线程

ulimit -u 指的是一个用户在同一时间最多能拥有的总进程(含线程)

ulimit 的进程数(含线程)受限于 pid_maxthreads-max

参考资料:

Understanding the difference between pid_max, ulimit -u and thread_max

Maximum number of threads per process in Linux?

查看运行现状

$ cat /proc/loadavg
0.41 0.45 0.57 3/749 28174
# 输出结果第四列含有被“/”分割的两个数字。
# 第一个数字表示当前可执行的内核调度实体(进程、线程)数量,通常小于或等于Cpu的数量。
# 第二个数字表示当前存在的内核调度实体,如上例当前并行存在749个线程 $ ps -elf | wc -l
220
# 当前进程数220(实际上减一行应为219),不包含进程创建的线程 $ ps -elfT | wc -l
385
# 当前线程数385(实际上减一行应为384),包含所有进程及线程 $ ps -p PID -lfT | wc -l
# 指定PID查看线程数,该线程数应该与Jstack生成的Thread Dump上的线程数一致 $ jstack -l PID | grep tid | wc -l
# jstack位于Jdk安装目录bin下,用于输出线程快照

/proc/loadavg的输出解释

减少JVM的线程栈大小

  • 一般不这么做,线程栈过小可能抛出java.lang.StackOverflowError异常,常见于旧版Maven编译失败。
  • 减少每个线程的栈大小有助于生成更多的线程。
  • 先检查当前JVM默认的线程栈大小
    $ java -XX:+PrintFlagsFinal -version | grep ThreadStackSize
    intx ThreadStackSize = 1024
    # 输出结果表示JVM默认线程栈大小为1M
  • 通过为JVM添加"-Xss",减少线程栈大小。
    JAVA_OPTS="-Xms128m -Xmx1303m -Xss256k"
    # 上述JVM参数表示JVM最小内存大小为128M,最大内存大小为1303M,线程栈大小为256K

解决Unable to create new native thread的更多相关文章

  1. java.lang.OutOfMemoryError: unable to create new native thread如何解决

    工作中碰到过这个问题好几次了,觉得有必要总结一下,所以有了这篇文章,这篇文章分为三个部分:认识问题.分析问题.解决问题. 一.认识问题: 首先我们通过下面这个 测试程序 来认识这个问题:运行的环境 ( ...

  2. 解决 - java.lang.OutOfMemoryError: unable to create new native thread

    工作中碰到过这个问题好几次了,觉得有必要总结一下,所以有了这篇文章,这篇文章分为三个部分:认识问题.分析问题.解决问题. 一.认识问题: 首先我们通过下面这个 测试程序 来认识这个问题: 运行的环境  ...

  3. 解决java.lang.OutOfMemoryError: unable to create new native thread问题

    解决:1.升级JVM到最新的版本 最新版本的JVM一般在内存优化方面做的更好,升级JVM到最新的版本可能会缓解测问题2.从操作系统层面去解决 使用64位操作系统 如果使用32位操作系统遇到unable ...

  4. 记一次tomcat线程创建异常调优:unable to create new native thread

    测试在进行一次性能测试的时候发现并发300个请求时出现了下面的异常: HTTP Status 500 - Handler processing failed; nested exception is ...

  5. java.lang.OutOfMemoryError: unable to create new native thread(转)

    解决 - java.lang.OutOfMemoryError: unable to create new native thread 工作中碰到过这个问题好几次了,觉得有必要总结一下,所以有了这篇文 ...

  6. spark大批量读取Hbase时出现java.lang.OutOfMemoryError: unable to create new native thread

    这个问题我去网上搜索了一下,发现了很多的解决方案都是增加的nproc数量,即用户最大线程数的数量,但我修改了并没有解决问题,最终是通过修改hadoop集群的最大线程数解决问题的. 并且网络上的回答多数 ...

  7. java.lang.OutOfMemoryError: unable to create new native thread 居然是MQ问题

    问题: 开发环境,之前一直正常,某天突然用tomcat启动项目后时不时报如下错误: java.lang.OutOfMemoryError: unable to create new native th ...

  8. JVM虚拟机宕机_java.lang.OutOfMemoryError: unable to create new native thread

    原因:当前用户的系统最最大程序数数已达到最大值,使用ulimit -u可以看到是1024   解决办法:在当前用户下使用ulimit -u 65535 然后再执行jsp,一切ok     功能说明:控 ...

  9. unable to create new native thread

    一.认识问题: 首先我们通过下面这个 测试程序 来认识这个问题:运行的环境 (有必要说明一下,不同环境会有不同的结果):32位 Windows XP,Sun JDK 1.6.0_18, eclipse ...

随机推荐

  1. 从tabBarController的一个item上的控制器跳转到另一个item上的控制器

    先从习惯性的tabBarController开始,很多应用的外框都是用这个开始的,而从tabBarController的一个item上的控制器跳转到另一个上的,往往都是直接通过点击tabBar上的不同 ...

  2. BOOST.Asio——Overview

    =================================版权声明================================= 版权声明:原创文章 谢绝转载  啥说的,鄙视那些无视版权随 ...

  3. 【转】高效Java编程工具集锦

    原文地址:http://geek.csdn.net/news/detail/57469 Java 开发者常常都会想办法如何更快地编写 Java 代码,让编程变得更加轻松.目前,市面上涌现出越来越多的高 ...

  4. Python写地铁的到站的原理简易版

    Python地铁的到站流程及原理(个人理解) 今天坐地铁看着站牌就莫名的想如果用Python写其工作原理 是不是很简单就小试牛刀了下大佬们勿喷纯属小弟个人理解 首先来看看地铁上显示的站牌如下: 就想这 ...

  5. Mac OS X常用操作入门指南

    前两天入手一个Macbook air,在装软件过程中摸索了一些基本操作,现就常用操作进行总结, 1关于触控板: 按下(不区分左右)            =鼠标左键 control+按下        ...

  6. 关于PB调用Microsoft Web Browser控件的一些问题

    Microsoft Web Browser控件是WINDOWS系统自带的控件,一般不需要单独安装,由于工作的需要,把使用中遇到的问题记录一下,以便查阅. 插入控件: 环境为PB12.0,insert- ...

  7. CML相关

    !!:执行上一条命令 !blah:执行最近的以 blah 开头的命令,如 !ls !blah:p:仅打印输出,而不执行 !$:上一条命令的最后一个参数,与 Alt + . 相同 !$:p:打印输出 ! ...

  8. 通过RTMP play分析FLV格式详解

    最近做了一个rtmp中转服务程序,通过实践,熟悉rtmp play和push中各类格式,这里总结一下. 程序github地址: https://github.com/runner365/rtmp_re ...

  9. 【Bootstrap Demo】入门例子创建

    本文简单介绍下如何来使用 Bootstrap,通过引入 Bootstrap,来实现一个最基本的入门例子. 在前一篇博文[Bootstrap]1.初识Bootstrap 基础之上,我们完全可以更加方便快 ...

  10. TCP的连接控制

    TCP的三次握手 所谓三次握手(Three-way Handshake),是指建立一个TCP连接时,需要客户端和服务器总共发送3个包. 确认号ack:期待收到对方下一个报文段的第一个数据字节的序号. ...