JAVA出现OOM问题的原因
1. 分配的内存空间小,正常的业务需要较大的内存空间
2. 对象频繁被申请,没有释放掉
3. 资源不断的申请,导致资源耗尽,如线程不断创建,不断的发起网络连接
定位OOM
1. 确定JVM的内存空间是否分配过小
jmap -heap pId
可以看出新生代、老年代的空间大小和使用情况
2. 找到最耗费内存对象
jmap -histo:live pId | more
可以看出存活对象的大小信息,找到耗费内存最大的那个对象,上图最大的对象是18M
3. 确定资源是否耗尽
工具:
ptree
netstat
这里介绍另一种方法,通过
ll /proc/<pid>/fd
ll /proc/<pid>/task
可以分别查看句柄详情和线程数。
例如,某一台线上服务器的sshd进程PID是9339,查看
ll /proc/9339/fd
ll /proc/9339/task
如上图,sshd共占用了四个句柄
0 -> 标准输入
1 -> 标准输出
2 -> 标准错误输出
3 -> socket(容易想到是监听端口)
sshd只有一个主线程PID为9339,并没有多线程。
所以,只要
ll /proc/${PID}/fd | wc -l
ll /proc/${PID}/task | wc -l (效果等同pstree -p | wc -l)
就能知道进程打开的句柄数和线程数。
转: https://blog.csdn.net/m0_37886429/article/details/77479344