最近因为太忙,时间不够,导致长时间没写笔录,没有好好去总结自己,很不应该,要调整回来。
这一次就记录一下,在生产中真实的 JVM
内存调优(内存分析)经历吧。
晚上领导电话过来说:服务怎么打不开了,是不是挂了?
(第一时间查看日志?不不不)
我:
在看日志的路上,突然发现当前服务器的 cpu
和 内存
全部跑满了。原来是因为CPU爆满,导致服务器呈现卡顿乃至是死机无法连接等状况。
OK啊,问题解决,买台更好的服务器就行了(哈哈)
一般 Java
应用 cpu
过高基本上是因为
但是 Java
项目很大,功能很多,如何知道是哪行代码出现问题呢?这时候就需要内存分析
了
在Linux终端输入:top -d 1
当前命令可以查看各个进程占用 cpu
情况,一般排名第一位肯定是 Java
进程,当然也可能存在多个 Java
进程
观察 top
消耗第一的资源是PID=12708
通过第一步知道消耗第一的进程,然后输入:ps -mp pid -o THREAD,tid,time
其中 pid
修改为 CPU
消耗第一的进程的pid
,也就是:ps -mp 12708 -o THREAD,tid,time
通过以上线程 CPU
切片,耗时在pid=12708,Tid=12723,耗时12分22秒,使用5.4%CPU。占用最大,时间最长。
TID
为12723的线程利用 cpu
资源比较多,怎么能看到这个线程在干什么呢?
第一步:需要将12723 转换为16进制,便于在jvm堆栈中查找,命令:printf "%x\n" 12723
。
当前指令会打印 12723
对应的16进制,也就是:31b3
第二步:通过 jstack
命令来查看下当前内存状态
命令:jstack pid | grep 对应的16进制 -A 30
如:jstack 12708 | grep 31b3 -A 30
(注意 下图pid和16进制不同)
这样就可以定位到是哪行代码出现问题,从而进行优化。
我的问题便是当前循环次数太大了,一直在运行,线程一直未被释放,然后下次请求很快又来了,从而又运行了一次循环代码,一直累加,导致CPU
跑满。
问题排查结束,在运行 Java
程序时。
当然真正的 JVM
调优远比这要复杂高深,这次只是浅浅的接触了 JVM
内存、 jstack
,但这次经历很有收获。
新年快乐,愿你我一直在前行!