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

出现场景

最近在部署一个省的项目时,遇到这个问题,该环境提供的服务器配置偏低,而项目本身为了性能,大量的使用的线程,导出出现 java.lang.OutOfMemoryError: unable to create new native thread异常

异常分析

这个异常问题本质原因是我们创建了太多的线程,而能创建的线程数是有限制的,导致了异常的发生。能创建的线程数的具体计算公式如下:

(MaxProcessMemory - JVMMemory - ReservedOsMemory) / (ThreadStackSize) = Number of threads

MaxProcessMemory         指的是一个进程的最大内存
JVMMemory                JVM内存
ReservedOsMemory         保留的操作系统内存
ThreadStackSize          线程栈的大小

在java语言里, 当你创建一个线程的时候,虚拟机会在JVM内存创建一个Thread对象同时创建一个操作系统线程,而这个系统线程的内存用的不是JVMMemory,而是系统中剩下的内存(MaxProcessMemory - JVMMemory - ReservedOsMemory)。由公式得出结论:你给JVM内存越多,那么你能创建的线程越少,越容易发生 java.lang.OutOfMemoryError: unable to create new native thread

解决思路

  1. 如果程序中有bug,导致创建大量不需要的线程或者线程没有及时回收,那么必须解决这个bug,修改参数是不能解决问题的。
  2. 如果程序确实需要大量的线程,现有的设置不能达到要求,那么可以通过修改MaxProcessMemory,JVMMemory,ThreadStackSize这三个因素,来增加能创建的线程数:
    • MaxProcessMemory 使用64位操作系统
    • VMMemory 减少 JVMMemory 的分配
    • ThreadStackSize 减小单个线程的栈大小

解决方案

  1. 适当牺牲性能,优化代码里面的线程池的线程配置。

  2. 减少 JVMMemory 的分配
    由于博主的项目是通过 Kubernetes 管理的,可以直接在对应的 yml 文件添加 jvm 的启动参数

     spec:
      containers:
      - image: dk.io/library/group-performance-service:0.0.8
        env:
          - name: "JAVA_OPTIONS"
            value: "-Xms256m -Xmx512m -Xss1m"
        name: res-gather
    

    重启工程后解决问题

后续

通过上述改动,程序在运行一段时间后,依然报内存溢出的错误!!!😱😱😱内心奔溃
没办法,接着分析错误原因

异常分析

上述都是在考虑线程的问题,线程又受到服务器进程的限制,难道是服务器上的进程数超最大限制了??😌😌😌
1.查看最大进程数 sysctl kernel.pid_max
在这里插入图片描述
2.查看当前进程数 ps -eLf | wc -l
在这里插入图片描述
观察发现有时后台定时任务启动的时候,当前进程数会超过系统的最大进程数限制!!!确认是进程数满了。

解决方案

1.修改最大进程数后系统恢复
echo 1000000 > /proc/sys/kernel/pid_max

2.永久生效
echo "kernel.pid_max=1000000 " >> /etc/sysctl.conf
sysctl -p

观察一段时间,服务器再也没有报内存溢出错误,问题解决 😊😊😊

  • 22
    点赞
  • 92
    收藏
    觉得还不错? 一键收藏
  • 7
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值