【问题排查】-bash: fork: retry: Resource temporarily unavailable 记录一下
● 最初现象,ssh 端口异常,登录机器出现如下,执行每一个命令都会有这个错,最终就是关闭终端后无法在连接,只能重启释放资源
● 查看kernel.threads-max(每个进程中最多创建的的线程数目)
● top -H 查看每个线程的资源使用情况 ,发现达到了当前系统限制 30938
● 修改threads-max , sysctl -w kernel.threads-max=3082609
● 恢复正常
● 查看 java 程序日志,发现每次出现问题都是 pod 日志很大的那台机器,怀疑是 java 程序内存泄漏,
- 线程泄漏:内存泄漏可能与线程泄漏相关联,即 Java 程序持续创建新的线程却没有正确终止它们,从而耗尽系统资源。在你调高系统线程限制后,线程数下降的现象表明之前存在大量不必要的线程,这些线程可能由于内存泄漏而未被正确回收。
- 频繁的垃圾回收(GC):如果大量对象占用内存,JVM 会频繁触发垃圾回收。当内存不足时,GC 可能会无法有效清理,导致更多的线程等待 GC 完成。这些情况都会导致系统资源耗尽。
- CPU 负载和内存竞争:内存泄漏导致的高内存占用会增加垃圾回收的频率,导致更高的 CPU 占用,从而可能拖慢整个系统。
你的当前系统情况
从你提供的 top
输出来看,系统中的线程数一度达到 30938,而在你调高线程限制后,线程数明显下降至 900 左右。这个明显的波动可能表明:
- Java 进程可能在某个时间点通过创建大量线程占用了大量系统资源,但没有正确地回收它们。
- 当系统限制解除后,这些不必要的线程可能被系统或应用程序终止,导致线程数迅速下降。
如何进一步排查内存泄漏
-
监控 Java 内存使用:使用
jmap
或jstat
来监控 Java 程序的堆内存使用情况。jstat -gcutil <PID> 1000
这可以帮助你了解 JVM 的垃圾回收情况,并判断内存泄漏的可能性。
-
线程分析:使用
jstack
来捕获线程转储(thread dump),查看是否存在大量处于等待状态的线程未能正确退出。jstack <PID> > thread_dump.txt
检查生成的
thread_dump.txt
文件,看看是否有大量相似的线程在等待某种锁或处于挂起状态。 -
GC 日志:启用 GC 日志来跟踪垃圾回收行为。通过分析 GC 日志,可以发现内存泄漏或频繁 GC 的迹象。
启用 GC 日志的命令行参数:-XX:+PrintGCDetails -XX:+PrintGCDateStamps -Xloggc:/path/to/gc.log
-
内存分析工具:使用
jmap
导出堆转储,并使用工具如 Eclipse MAT 或 VisualVM 来分析内存泄漏。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
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 25岁的心里话
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 零经验选手,Compose 一天开发一款小游戏!
· 通过 API 将Deepseek响应流式内容输出到前端
· 因为Apifox不支持离线,我果断选择了Apipost!