今天 服务器启动服务时 ,日志突然报错:
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 org.eclipse.jetty.util.thread.QueuedThreadPool.startThreads(QueuedThreadPool.java:447)
at org.eclipse.jetty.util.thread.QueuedThreadPool.access$200(QueuedThreadPool.java:47)
at org.eclipse.jetty.util.thread.QueuedThreadPool$3.run(QueuedThreadPool.java:598)
at java.lang.Thread.run(Thread.java:745)
WARN [2020-12-10 09:57:22,366] ({qtp1418428263-604} QueuedThreadPool.java[run]:617) - Unexpected thread death: org.eclipse.jetty.util.thread.QueuedThreadPool$3@63990f18 in qtp1418428263{STARTED,8<=9<=200,i=0,q=0}
赶紧开始检查错误:
首先参考 牛逼的二进制 的博客
找到诱发原因:
一般由于两个原因导致的:
- 1)内存空间不足以满足创建线程所需的stack size
virtual memory < stack size*the number of threads - 2)线程数已达到操作系统的上限
跟随博客开始排查错误:
1 查看虚拟机jvm
java -XX:+PrintFlagsFinal -version | grep ThreadStackSize
结果:
intx CompilerThreadStackSize = 0 {pd product}
intx ThreadStackSize = 1024 {pd product}
intx VMThreadStackSize = 1024 {pd product}
java version "1.8.0_101"
Java(TM) SE Runtime Environment (build 1.8.0_101-b13)
Java HotSpot(TM) 64-Bit Server VM (build 25.101-b13, mixed mode)
2 查看虚拟机jvm
进程可用最大虚拟内存
ulimit -v
结果:unlimited
最大栈大小
ulimit -s
结果:8192
每个用户可创建最大进程数
ulimit -u
结果: 510226
整体信息查看
ulimit -a
结果:
core file size (blocks, -c) unlimited
data seg size (kbytes, -d) unlimited
scheduling priority (-e) 0
file size (blocks, -f) unlimited
pending signals (-i) 514740
max locked memory (kbytes, -l) 64
max memory size (kbytes, -m) unlimited
open files (-n) 1048576
pipe size (512 bytes, -p) 8
POSIX message queues (bytes, -q) 819200
real-time priority (-r) 0
stack size (kbytes, -s) 8192
cpu time (seconds, -t) unlimited
max user processes (-u) 1048576
virtual memory (kbytes, -v) unlimited
file locks (-x) unlimited
在设置上并不存在过小的问题,所以继续排查。
3 利用pstree查看进程
pstree -up # 查看用户和pid号
pstree # 基础查询
部分截图:
发现并没有出现 某个程序 启动多个线程情况,继续
4 查看内存情况
free -h
发现问题 :
发现Swap 使用过高(上图是wokill掉某个程序后的结果),free只剩下400m。
查看占用swap前N的程序的PID和占用内存: (head -20 可自行调整)
> for i in $( cd /proc;ls |grep "^[0-9]"|awk ' $0 >100') ;do awk '/Swap:/{a=a+$2}END{print '"$i"',a/1024"M"}' /proc/$i/smaps 2>/dev/null ; done | sort -k2nr | head -20
发现有多个文件占用超过1G,查看PID是什么操作
ps -ef | grep 34819
发现是某个无用任务,直接
kill -9 34819
发现swap 占用下降,连续删除多个无用任务后,swap占用正常。
PS: 可以使用 top -c 查看占用进程内存 CPU情况!