java.lang.OutOfMemoryError- unable to create new native thread 问题排查

这篇具有很好参考价值的文章主要介绍了java.lang.OutOfMemoryError- unable to create new native thread 问题排查。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

问题描述

最近连续两天大约凌晨3点,线上服务开始异常,出现OOM报错。且服务所在的物理机只能ping通,但是无法登录。报错信息如下:

ERROR 04-12 03:01:43,930 [DefaultQuartzScheduler_Worker-3] JobRunShell[JobRunShell]:211 Job threw an unhandled Exception:
java.lang.OutOfMemoryError: unable to create new native thread
        at java.lang.Thread.start0(Native Method)
        at java.lang.Thread.start(Thread.java:714)
        at java.util.concurrent.ForkJoinPool.createWorker(ForkJoinPool.java:1483)
        ...
        at org.quartz.core.JobRunShell.run(JobRunShell.java:202)
        at org.quartz.simpl.SimpleThreadPool$WorkerThread.run(SimpleThreadPool.java:573)

排查过程

根据日志OOM报错,怀疑是内存不足或内存泄露的原因,需要查看内存的使用情况。考虑到JConsoleVisualVM具有可视化界面,能看出历史变化趋势,更直观地排查问题,因此为程序配置了jmx参数。重启应用,使用VisualVM连接应用的jmx端口。应用配置jmx端口的参数如下:

-Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.authenticate=false  -Dcom.sun.management.jmxremote.ssl=false -Dcom.sun.management.jmxremote.port=9998

VisualVM显示使用的内存是正常的,没有持续飙升。但是线程数却比较异常,随时间推移在持续增加。因此考虑看看是什么线程在持续增加,jstack是一个比较好用的工具,它用于生成 JAVA 虚拟机当前时刻的线程快照。

java.lang.OutOfMemoryError- unable to create new native thread 问题排查

使用jstack -F PID打印出了所有线程,发现有大片下面的堆栈信息。注意到com.xxx.http.IdleConnectionMonitorThread.run() @bci=15, line=22 (Compiled frame)方法出现的特别多。

Thread 7760: (state = BLOCKED)
 - sun.misc.Unsafe.park(boolean, long) @bci=0 (Compiled frame; information may be imprecise)
 - java.util.concurrent.ForkJoinPool.awaitWork(java.util.concurrent.ForkJoinPool$WorkQueue, int) @bci=354, line=1821 (Compiled frame)
 - java.util.concurrent.ForkJoinPool.runWorker(java.util.concurrent.ForkJoinPool$WorkQueue) @bci=44, line=1690 (Compiled frame)
 - java.util.concurrent.ForkJoinWorkerThread.run() @bci=24, line=157 (Compiled frame)


Thread 7759: (state = BLOCKED)
 - java.lang.Object.wait(long) @bci=0 (Compiled frame; information may be imprecise)
 - com.xxx.http.IdleConnectionMonitorThread.run() @bci=15, line=22 (Compiled frame)
 - java.lang.Thread.run() @bci=11, line=745 (Compiled frame)


Thread 7758: (state = BLOCKED)
 - java.lang.Object.wait(long) @bci=0 (Compiled frame; information may be imprecise)
 - com.xxx.http.IdleConnectionMonitorThread.run() @bci=15, line=22 (Compiled frame)
 - java.lang.Thread.run() @bci=11, line=745 (Compiled frame)

在项目搜索类IdleConnectionMonitorThread,并查看22行内容。发现如果不执行shutdown()方法,那么该后台线程会持续地执行wait()方法,导致该线程不退出。实际情况是确实没有执行shutdown()方法,随着每10分钟执行一次计算任务,每次计算任务会执行一批http请求,每个http请求就会创建出一个后台线程,这样会导致线程数越来越多。

java.lang.OutOfMemoryError- unable to create new native thread 问题排查

联系了sdk的提供方,提供了后台进程的停止方法。在程序请求http完成后,释放请求的资源,停止了后台线程。使用VisualVm观察了一段时间,发现线程数不在增长了,未出现OOM报错。至此问题解决。

java.lang.OutOfMemoryError- unable to create new native thread 问题排查

虽然问题解决了,不过还有个疑问,线程数达到多少会触发unable to create new native thread报错。查阅博客了解到,一个进程最多能创建多少线程是受多因素影响的,基本上是系统支持的最大PID、用户可创建最大线程数、系统支持的最大线程数的最小值。通过查看服务器配置,系统支持的最大PID的值是最小的:32768,也就是说一个进程最多创建大约3w个线程。由于服务器上部署了线上服务,不方便在复现验证创建多少个线程时出现OOM报错。

java.lang.OutOfMemoryError: unable to create new native thread问题排查以及当前系统最大进程数量

一个JVM可以创建多少线程,首先由JVM设置决定(-Xms,-Xmx,-Xss),另外受到外部因素影响,就是系统设置(最大PID、最大线程、栈内存大小、最重要的还是物理内存由多少)、其二就是用户设置(用户可以运行多少个进程或线程),综合上述因素的最小值就是一个JVM可以创建多少线程。

系统支持的最大进程数
cat /proc/sys/kernel/pid_max
32768

系统支持的最大线程数
cat /proc/sys/kernel/threads-max
513024

进程可用最大虚拟内存
ulimit -v
unlimited

最大栈大小
ulimit -s
8192

每个用户可创建最大进程数
ulimit -u
256512

总结

1.JConsoleVisualVM具有可视化界面,可以方便地查看CPU占用、内存使用、类数量、线程数的历史变化趋势。

2.jstack命令可以查看正在运行的程序当前时刻的所有线程信息。

3.一个进程最多能创建多少线程,是受多因素影响的,基本上是系统支持的最大PID、用户可创建最大线程数、系统支持的最大线程数的最小值。文章来源地址https://www.toymoban.com/news/detail-412606.html

参考资料

  • java.lang.OutOfMemoryError: unable to create new native thread(CSDN)
  • java.lang.OutOfMemoryError: unable to create new native thread问题排查以及当前系统最大进程数量
  • java.lang.OutOfMemoryError: unable to create new native thread(简书)

到了这里,关于java.lang.OutOfMemoryError- unable to create new native thread 问题排查的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包赞助服务器费用

相关文章

  • Caused by: java.lang.reflect.InaccessibleObjectException: Unable to make protected final java.lang.C

    Caused by: java.lang.reflect.InaccessibleObjectException: Unable to make protected final java.lang.C

    最近在学习JDK17的时候遇到这么一个问题,springBoot启动失败,日志如下: 原因:这是由于 JDK 8 中有关反射相关的功能自从 JDK 9 开始就已经被限制了,为了兼容原先的版本,需要在运行项目时添加  --add-opens java.base/java.lang=ALL-UNNAMED  选项来开启这种默认不被允许的行为。 解

    2024年02月03日
    浏览(40)
  • Android报错:java.lang.RuntimeException: Unable to start activity ComponentInfo

    在A类去继承AppCompatActivity,用B类去继承A类时,出现了这样的错误: java.lang.RuntimeException: Unable to start activity ComponentInfo  目前尚未找出错误,也未能理解。 试着让B类去继承Activity时 ,登录之后页面也是可以进行跳转的,但是写的东西用到了一些方法,例如:getSupportFragmentM

    2024年02月06日
    浏览(10)
  • java.lang.IllegalStateException Unable to find a @SpringBootConfiguration代码报错

    java.lang.IllegalStateException Unable to find a @SpringBootConfiguration代码报错

    使用idea基于springBoot的项目进行单元测试时,出现异常,如下所示: 该测试类在运行时找不到启动类,所以报错 ①检查项目中有没有写启动类,如果没写,赶紧补上 正确的启动类示例代码如下: ps:启动类的类名随便写,但推荐 见名知义 的命名原则 ②如果你写了启动类,

    2024年02月17日
    浏览(40)
  • 遇到:java.lang.reflect.InaccessibleObjectException: Unable to make 错误应该如何解决

    遇到 \\\"java.lang.reflect.InaccessibleObjectException: Unable to make...\\\" 错误是由于Java的反射机制无法访问或调用一个非公共的方法、字段或构造函数所引发的异常。这是由于Java的安全管理器或访问控制机制限制了对非公共成员的访问。 要解决这个问题,你可以尝试以下方法: 检查访问修

    2024年02月09日
    浏览(43)
  • 遇到:java.lang.reflect.InaccessibleObjectException: Unable to make错误应该如何解决

    遇到 \\\"java.lang.reflect.InaccessibleObjectException: Unable to make\\\" 错误是因为你的代码尝试访问了一个不可访问的对象或方法。这通常会发生在使用反射机制时,尝试访问私有或受限制的成员时。要解决这个问题,你可以考虑以下几个步骤: 检查访问修饰符:检查你尝试访问的对象或方

    2024年02月07日
    浏览(40)
  • jdk 8以上版本报错 :Unable to make field protected java.lang.reflect.InvocationHandler java.lang.reflect...

    具体报错信息: Unable to make field protected java.lang.reflect.InvocationHandler java.lang.reflect.Proxy.h accessible: module java.base does not \\\"opens java.lang.reflect\\\" to unnamed module @7674f035 需要设置启动参数 --add-opens java.base/java.lang.reflect=ALL-UNNAMED

    2024年02月20日
    浏览(54)
  • Mybatis Plus 报错Caused by: java.lang.reflect.InaccessibleObjectException: Unable to make

    Mybatis Plus 报错Caused by: java.lang.reflect.InaccessibleObjectException: Unable to make

    报错信息 这原本是我使用MyBatis Plus配合Lambda表达式做一个模糊查询,但是报了这么个错误,以下为源代码,语法上是没啥问题的 语法上并没有什么错误,但是运行报错,百度了一番之后,发现只需要降低一下Mybat Plus的版本坐标,降到3.4.0或者以下即可 我原先好像是3.4.2,改

    2024年02月16日
    浏览(70)
  • 关于报错java.lang.reflect.InaccessibleObjectException: Unable to make field private java.util.concurrent

    java.lang.reflect.InaccessibleObjectException: Unable to make field private java.util.concurrent.Callable java.util.concurrent.FutureTask.callable accessible: module java.base does not \\\"opens java.util.concurrent\\\" to unnamed module @32eebfca 假如报这种错误,只需要在Run-Edit Configurations-Modify Options-add VM options中加  假如你报的是下面

    2024年02月15日
    浏览(45)
  • FAILED: HiveException java.lang.RuntimeException: Unable to instantiate org.apache.hadoop.hiv

    FAILED: HiveException java.lang.RuntimeException: Unable to instantiate org.apache.hadoop.hiv

    Hive报错 FAILED: HiveException java.lang.RuntimeException: Unable to instantiate org.apache.hadoop.hive.ql.metadata.SessionHiveMetaStoreClient 的解决方法 【注意:在那个目录下进入Hive,就会在相应的目录下生成对应的metastore_db,我是在/root 目录下进入的hive,则在 /root 目录下就可以看到对应的metastore_db】 进

    2024年02月03日
    浏览(11)
  • 安装JDK:Unable to make field private final java.lang.String java.io.File.path accessible

    安装JDK:Unable to make field private final java.lang.String java.io.File.path accessible

    BUILD FAILED Unable to make field private final java.lang.String java.io.File.path accessible: module java.base does not “opens java.io” to unnamed module @63f6847a 解决办法:JDK改为17以下即可。例如我改为11,直接就OK了 另外经常编译项目 强烈建议大家 能配置多个编译环境。直接terminal中./gradlew assembleReleas

    2024年02月02日
    浏览(13)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包