【问题排查】-bash: fork: retry: Resource temporarily unavailable 记录一下

● 最初现象,ssh 端口异常,登录机器出现如下,执行每一个命令都会有这个错,最终就是关闭终端后无法在连接,只能重启释放资源

● 查看kernel.threads-max(每个进程中最多创建的的线程数目)

● top -H 查看每个线程的资源使用情况 ,发现达到了当前系统限制 30938

● 修改threads-max , sysctl -w kernel.threads-max=3082609

● 恢复正常

● 查看 java 程序日志,发现每次出现问题都是 pod 日志很大的那台机器,怀疑是 java 程序内存泄漏,

  1. 线程泄漏:内存泄漏可能与线程泄漏相关联,即 Java 程序持续创建新的线程却没有正确终止它们,从而耗尽系统资源。在你调高系统线程限制后,线程数下降的现象表明之前存在大量不必要的线程,这些线程可能由于内存泄漏而未被正确回收。
  2. 频繁的垃圾回收(GC):如果大量对象占用内存,JVM 会频繁触发垃圾回收。当内存不足时,GC 可能会无法有效清理,导致更多的线程等待 GC 完成。这些情况都会导致系统资源耗尽。
  3. CPU 负载和内存竞争:内存泄漏导致的高内存占用会增加垃圾回收的频率,导致更高的 CPU 占用,从而可能拖慢整个系统。

你的当前系统情况

从你提供的 top 输出来看,系统中的线程数一度达到 30938,而在你调高线程限制后,线程数明显下降至 900 左右。这个明显的波动可能表明:

  • Java 进程可能在某个时间点通过创建大量线程占用了大量系统资源,但没有正确地回收它们。
  • 当系统限制解除后,这些不必要的线程可能被系统或应用程序终止,导致线程数迅速下降。

如何进一步排查内存泄漏

  1. 监控 Java 内存使用:使用 jmapjstat 来监控 Java 程序的堆内存使用情况。

    jstat -gcutil <PID> 1000
    

    这可以帮助你了解 JVM 的垃圾回收情况,并判断内存泄漏的可能性。

  2. 线程分析:使用 jstack 来捕获线程转储(thread dump),查看是否存在大量处于等待状态的线程未能正确退出。

    jstack <PID> > thread_dump.txt
    

    检查生成的 thread_dump.txt 文件,看看是否有大量相似的线程在等待某种锁或处于挂起状态。

  3. GC 日志:启用 GC 日志来跟踪垃圾回收行为。通过分析 GC 日志,可以发现内存泄漏或频繁 GC 的迹象。
    启用 GC 日志的命令行参数:

    -XX:+PrintGCDetails -XX:+PrintGCDateStamps -Xloggc:/path/to/gc.log
    
  4. 内存分析工具:使用 jmap 导出堆转储,并使用工具如 Eclipse MATVisualVM 来分析内存泄漏。

    jmap -dump:format=b,file=heapdump.hprof <PID>
    

    然后使用 Eclipse MAT 等工具分析生成的 .hprof 文件,查找是否有持续增长的对象占用大量内存。

结论

你的系统可能存在 Java 线程泄漏或内存泄漏问题,这导致了大量的线程和内存占用。随着系统资源的耗尽,调高线程限制暂时解决了这个问题,但仍需要深入排查 Java 应用中的内存和线程管理,使用 GC 日志和堆转储分析工具来找出问题的根本原因。
参考连接:
https://ivanzz1001.github.io/records/post/linux/2017/07/31/linux-thread-limit

posted @   broadviews  阅读(202)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 25岁的心里话
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 零经验选手,Compose 一天开发一款小游戏!
· 通过 API 将Deepseek响应流式内容输出到前端
· 因为Apifox不支持离线,我果断选择了Apipost!
点击右上角即可分享
微信分享提示