cpu负载查看方法:
使用vmstat查看系统维度的cpu负载
使用top查看进程维度的cpu负载
1、使用 vmstat 查看系统纬度的 cpu 负载:
可以通过 vmstat 从系统维度查看 cpu 资源的使用情况。
用法说明:
格式:vmstat -n 1# -n 1 表示结果一秒刷新一次。示例输出:
[root@wangerxiao ~]# vmstat -t 1
procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu----- -----timestamp-----
r b swpd free buff cache si so bi bo in cs us sy id wa st cst
3 0 0 5910832 134096 3931732 0 0 0 1 0 1 0 0 100 0 0 2016-11-13 19:57:36
0 0 0 5910816 134096 3931732 0 0 0 0 274 511 0 0 100 0 0 2016-11-13 19:57:37
回显说明:
返回结果中的主要数据列说明:
r: 表示系统中 cpu 等待处理的线程。由于 cpu 每次只能处理一个线程,所以,该数值越大,通常表示系统运行越慢。
us:用户模式消耗的 cpu 时间百分比。该值较高时,说明用户进程消耗的 cpu 时间比较多,比如,如果该值长期超过 50%,则需要对程序算法或代码等进行优化。
sy:内核模式消耗的 cpu 时间百分比。
wa:io 等待消耗的 cpu 时间百分比。该值较高时,说明 io 等待比较严重,这可能磁盘大量作随机访问造成的,也可能是磁盘性能出现了瓶颈。
id:处于空闲状态的 cpu 时间百分比。如果该值持续为 0,同时 sy 是 us 的两倍,则通常说明系统则面临着 cpu 资源的短缺。
回显说明:
返回结果中的主要数据列说明:
r: 表示系统中 cpu 等待处理的线程。由于 cpu 每次只能处理一个线程,所以,该数值越大,通常表示系统运行越慢。
us:用户模式消耗的 cpu 时间百分比。该值较高时,说明用户进程消耗的 cpu 时间比较多,比如,如果该值长期超过 50%,则需要对程序算法或代码等进行优化。
sy:内核模式消耗的 cpu 时间百分比。
wa:io 等待消耗的 cpu 时间百分比。该值较高时,说明 io 等待比较严重,这可能磁盘大量作随机访问造成的,也可能是磁盘性能出现了瓶颈。
id:处于空闲状态的 cpu 时间百分比。如果该值持续为 0,同时 sy 是 us 的两倍,则通常说明系统则面临着 cpu 资源的短缺。
2、使用 top 查看进程纬度的 cpu 负载:
可以通过 top 从进程纬度来查看其 cpu、内存等资源的使用情况。
用法说明:格式:top示例输出
[root@wangerxiao ~]# top
top - 20:02:37 up 35 days, 23:33, 2 users, load average: 0.00, 0.01, 0.05
tasks: 296 total, 1 running, 295 sleeping, 0 stopped, 0 zombie
%cpu(s): 0.1 us, 0.1 sy, 0.0 ni, 99.8 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st
kib mem : 12139008 total, 5998320 free, 2074896 used, 4065792 buff/cache
kib swap: 2098172 total, 2098172 free, 0 used. 9739056 avail mem
pid user pr ni virt res shr s %cpu %mem time command
1006 influxdb 20 0 5001836 332224 11568 s 1.0 2.7 1172:51 influxd
3578 icinga 20 0 1399032 12792 5152 s 0.3 0.1 136:59.57 icinga2
30207 root 20 0 40800 2120 1328 r 0.3 0.0 0:00.10 top
1 root 20 0 196848 11904 2348 s 0.0 0.1 7:32.27 systemd
2 root 20 0 0 0 0 s 0.0 0.0 0:02.22 kthreadd
3 root 20 0 0 0 0 s 0.0 0.0 0:00.71 ksoftirqd/0
5 root 0 -20 0 0 0 s 0.0 0.0 0:00.00 kworker/0:0h
回显说明:
默认界面上第三行会显示当前 cpu 资源的总体使用情况,下方会显示各个进程的资源占用情况。
可以直接在界面输入大小字母 p,来使监控结果按 cpu 使用率倒序排列,进而定位系统中占用 cpu 较高的进程。最后,根据系统日志和程序自身相关日志,对相应进程做进一步排查分析,以判断其占用过高 cpu 的原因。
操作案列:
3、hping3
hping3 是一个可以构造 tcp/ip 协议数据包的工具,可以对系统进行安全审计、防火墙测试等。运行 hping3 命令,来模拟 nginx 的客户端请求
# -s参数表示设置tcp协议的syn(同步序列号),-p表示目的端口为80
# -i u100表示每隔100微秒发送一个网络帧
# 注:如果你在实践过程中现象不明显,可以尝试把100调小,比如调成10甚至1
$ hping3 -s -p 80 -i u100 192.168.0.30
虽然在运行 hping3 命令时,我就已经告诉你,这是一个 syn flood 攻击,你肯定也会想到从网络方面入手,来分析这个问题。不过,在实际的生产环境中,没人直接告诉你原因。
4、tcpdump
# -i eth0 只抓取eth0网卡,-n不解析协议名和主机名
# tcp port 80表示只抓取tcp协议并且端口号为80的网络帧
$ tcpdump -i eth0 -n tcp port 80
15:11:32.678966 ip 192.168.0.2.18238 > 192.168.0.30.80: flags [s], seq 458303614, win 512, length 0
...
yum -y install perf sysstat dstat(perf pidstat)
top,htop
pidstat——专门分析每个进程cpu使用情况的工具
pidstat -p $pid
perf——perf是linux2.6.31以后内置的性能分析工具。它以性能事件采样为基础,不仅可以分析系统的各种事件和内核性能,还可以分析指定应用程序的性能问题。是内置于linux内核源码数中的性能剖析工具,常用于性能瓶颈的查找和热点代码的定位
perf top主要是用于分析各个函数在某个性能事件上的热度,能够快速的定位热点函数,包括应用程序函数
execsnoop 就是一个专为短时进程设计的工具。它通过 ftrace 实时监控进程的 exec() 行为,并输出短时进程的基本信息,包括进程 pid、父进程 pid、命令行参数以及执行的结果
dstat 它吸收了 vmstat、iostat、ifstat 等几种工具的优点,可以同时观察系统的 cpu、磁盘 i/o、网络以及内存使用情况
strace 正是最常用的跟踪进程系统调用的工具
pstree查找父进程
sar 是一个系统活动报告工具,既可以实时查看系统的当前活动,又可以配置保存和报告历史统计数据。
tcpdump 是一个常用的网络抓包工具,常用来分析各种网络问题。
【yum -y install hping3 tcpdump】
使用top直接终止cpu消耗较大的进程
注意 :# 按下数字 1 切换到所有 cpu 的使用情况,观察一会儿按 ctrl c 结束。
如前面所述,可以通过 top 命令查看系统的负载问题,并定位耗用较多 cpu 资源的进程。
可以直接在 top 运行界面快速终止相应的异常进程。说明如下:
1,想要终止某个进程,只需按下小写的 k 键。
2,输入想要终止的进程 pid (top 输出结果的第一列)。比如,如下图所示,假如想要终止 pid 为 23 的进程,输入 23 后按回车。
**参数介绍 : **
* us:用户态cpu时间
* sy:内核态cpu时间
* ni:低优先级用户态cpu时间
* id:空闲时间
* wa:等待i/o的cpu时间
* hi:处理硬中断的cpu时间
* si:处理软中断的cpu时间
* st:当系统运行在虚拟机中的时候,被其他虚拟机占用的cpu时间
进程状态:
r(running) 表示进程在cpu的就绪队列中,正在运行或者正在等待运行
d(disk sleep) 不可中断状态睡眠,一般表示进程正在和硬件交互,并且交互过程不允许被其他进程或中断打断【系统硬件出现故障会导致此进程增多,需关注是不是i/o等性能问题】
z(zombie) 僵尸进程 ,也就是进程实际上已经结束了,但是父进程还没有收回它的资源(比如进程的描述符,pid等)
s(interruptible sleep) 也就是可中断状态失眠,表示进程因为等待某个事件而被系统挂起。当进程等待事件发生时,它会被唤醒并进入r状态。
i(idel) 空闲状态,用在不可中断睡眠的内核线程上,硬件交互导致的不可中断进程用d表示,但对于某些内核进程来说,它们又可能实际上并没有任何负载,用idel正是为了区分这种情况,要注意,d状态的进程会导致平均负载升高,i状态的进程不会
t或者t,也就是stopped或traced的缩写,表示进程处于暂停或者跟踪状态
x(dead)表示进程已经消亡,不会在top中查看到
进程组表示一组相互关联的进程,比如每个子进程都是父进程所在组的成员;
会话是指共享同一个控制终端的一个或多个进程组。
3,如下图所示,操作成功后,界面会出现类似 “send pid 23 signal [15/sigterm]” 的提示信息让用户进行确认。按回车确认即可
# 间隔1秒输出10组数据
$ dstat 1 10
you did not select any stats, using -cdngy by default.
--total-cpu-usage-- -dsk/total- -net/total- ---paging-- ---system--
usr sys idl wai stl| read writ| recv send| in out | int csw
0 0 96 4 0|1219k 408k| 0 0 | 0 0 | 42 885
0 0 2 98 0| 34m 0 | 198b 790b| 0 0 | 42 138
0 0 0 100 0| 34m 0 | 66b 342b| 0 0 | 42 135
0 0 84 16 0|5633k 0 | 66b 342b| 0 0 | 52 177
0 3 39 58 0| 22m 0 | 66b 342b| 0 0 | 43 144
0 0 0 100 0| 34m 0 | 200b 450b| 0 0 | 46 147
0 0 2 98 0| 34m 0 | 66b 342b| 0 0 | 45 134
0 0 0 100 0| 34m 0 | 66b 342b| 0 0 | 39 131
0 0 83 17 0|5633k 0 | 66b 342b| 0 0 | 46 168
0 3 39 59 0| 22m 0 | 66b 342b| 0 0 | 37 134
从 dstat 的输出,我们可以看到,每当 iowait 升高(wai)时,磁盘的读请求(read)都会很大。这说明 iowait 的升高跟磁盘的读请求有关,很可能就是磁盘读导致的。
# 每隔1秒输出一组数据,共输出5组
$ pidstat 1 5
15:56:02 uid pid %usr %system %guest %wait %cpu cpu command
15:56:03 0 15006 0.00 0.99 0.00 0.00 0.99 1 dockerd
...
average: uid pid %usr %system %guest %wait %cpu cpu command
average: 0 15006 0.00 0.99 0.00 0.00 0.99 - dockerd
-----------------
-----------------
用户态 cpu 使用率 (%usr)
内核态 cpu 使用率(%system)
运行虚拟机 cpu 使用率(%guest)
等待 cpu 使用率(%wait)
以及总的 cpu 使用率(%cpu)
# -d 展示 i/o 统计数据,-p 指定进程号,间隔 1 秒输出 3 组数据
$ pidstat -d -p 4344 1 3
06:38:50 uid pid kb_rd/s kb_wr/s kb_ccwr/s iodelay command
06:38:51 0 4344 0.00 0.00 0.00 0 app
06:38:52 0 4344 0.00 0.00 0.00 0 app
06:38:53 0 4344 0.00 0.00 0.00 0 app
在这个输出中, kb_rd 表示每秒读的 kb 数, kb_wr 表示每秒写的 kb 数,iodelay 表示 i/o 的延迟(单位是时钟周期)。它们都是 0,那就表示此时没有任何的读写,说明问题不是 4344 进程导致的。
pidstat -w -u 1 -w代表进程切换指标,-u表示输出cpu使用指标,每隔1s输出1组数据
average: uid pid %usr %system %guest %cpu cpu command
vmstat 5
重点关注:
io
- bi 从块设备接收的块(block/s)
- bo 发送给块设备的块(block/s).如果这个值长期不为0,说明内存可能有问题,因为没有使用到缓存(当然,不排除直接i/o的情况,但是一般很少有直接i/o的)
system
- in (interrupt) 每秒的中断次数,包括时钟中断,需要关注,这两个值越大,内核消耗cpu会越大
- cs (context switch) 进程上下文切换次数,需要关注
cpu
- us 用户进程占用cpu时间比例,需要关注us sy是否已经为100%
- sy 系统占用cpu时间比例
- id cpu空闲时间比
- wa io等待时间比(io等待高时,可能是磁盘性能有问题了)
- st steal time
proc
r (running or runnnable)是就绪队列的长度,也就是正在运行和等待cpu的进程数。对比cpu的个数,如果等待进程大于cpu个数,需要注意
b (blocked) 则是处于不可中断睡眠状态的进程数
strace 正是最常用的跟踪进程系统调用的工具。所以,我们从 pidstat 的输出中拿到进程的 pid 号,比如 6082,然后在终端中运行 strace 命令,并用 -p 参数指定 pid 号
$ strace -p 6082
strace: attach: ptrace(ptrace_seize, 6082): operation not permitted
这儿出现了一个奇怪的错误,strace 命令居然失败了,并且命令报出的错误是没有权限。按理来说,我们所有操作都已经是以 root 用户运行了,为什么还会没有权限呢?你也可以先想一下,碰到这种情况,你会怎么处理呢?一般遇到这种问题时,我会先检查一下进程的状态是否正常。比如,继续在终端中运行 ps 命令,并使用 grep 找出刚才的 6082 号进程:
果然,进程 6082 已经变成了 z 状态,也就是僵尸进程。僵尸进程都是已经退出的进程,所以就没法儿继续分析它的系统调用。关于僵尸进程的处理方法,我们一会儿再说,现在还是继续分析 iowait 的问题。到这一步,你应该注意到了,系统 iowait 的问题还在继续,但是 top、pidstat 这类工具已经不能给出更多的信息了。这时,我们就应该求助那些基于事件记录的动态追踪工具了。你可以用 perf top 看看有没有新发现。再或者,可以像我一样,在终端中运行 perf record,持续一会儿(例如 15 秒),然后按 ctrl c 退出,再运行 perf report 查看报告:
$ perf top
samples: 833 of event 'cpu-clock', event count (approx.): 97742399
overhead shared object symbol
7.28% perf [.] 0x00000000001f78a4
4.72% [kernel] [k] vsnprintf
4.32% [kernel] [k] module_get_kallsym
3.65% [kernel] [k] _raw_spin_unlock_irqrestore
...
类似与top,它能够实时显示占用cpu时钟最多的函数或者指令,因此可以用来查找热点函数
输出结果中,第一行包含三个数据,分别是采样数(samples)、事件类型(event)和事件总数量(event count)。
比如这个例子中,perf 总共采集了 833 个 cpu 时钟事件,而总事件数则为 97742399。
另外,采样数需要我们特别注意。如果采样数过少(比如只有十几个),那下面的排序和百分比就没什么实际参考价值了。
再往下看是一个表格式样的数据,每一行包含四列,分别是:
第一列 overhead ,是该符号的性能事件在所有采样中的比例,用百分比来表示。
第二列 shared ,是该函数或指令所在的动态共享对象(dynamic shared object),如内核、进程名、动态链接库名、内核模块名等。第三列 object ,是动态共享对象的类型。比如 [.] 表示用户空间的可执行程序、或者动态链接库,而 [k] 则表示内核空间。
最后一列 symbol 是符号名,也就是函数名。
当函数名未知时,用十六进制的地址来表示。还是以上面的输出为例,我们可以看到,占用 cpu 时钟最多的是 perf 工具自身,不过它的比例也只有 7.28%,说明系统并没有 cpu 性能问题。 perf top 的使用你应该很清楚了吧。
查看top发现
有6个r状态的进程,查看却是stress(测试)进程
$ pidstat -p 24344(进程id)
16:14:55 uid pid %usr %system %guest %wait %cpu cpu command
# 从所有进程中查找pid是24344的进程
$ ps aux | grep 24344
root 9628 0.0 0.0 14856 1096 pts/0 s 16:15 0:00 grep --color=auto 24344
pstree 就可以用树状形式显示所有进程之间的关系:
$ pstree | grep stress
找到父进程后,再继续排查
用 execsnoop 监控上述案例,就可以直接得到 stress 进程的父进程 pid 以及它的命令行参数,并可以发现大量的 stress 进程在不停启动
# 按 ctrl c 结束
$ execsnoop
cpu使用率较低但负载较高
问题描述:
linux 系统没有业务程序运行,通过 top 观察,类似如下图所示,cpu 很空闲,但是 load average 却非常高:
处理办法:
load average 是对 cpu 负载的评估,其值越高,说明其任务队列越长,处于等待执行的任务越多。
出现此种情况时,可能是由于僵死进程导致的。可以通过指令 ps -axjf 查看是否存在 d 状态进程。
d 状态是指不可中断的睡眠状态。该状态的进程无法被 kill,也无法自行退出。只能通过恢复其依赖的资源或者重启系统来解决。
kswapd0 进程占用 cpu 较高
操作系统都用分页机制来管理物理内存,操作系统将磁盘的一部分划出来作为虚拟内存,由于内存的速度要比磁盘快得多,所以操作系统要按照某种换页机制将不需要的页面换到磁盘中,将需要的页面调到内存中,由于内存持续不足,这个换页动作持续进行,kswapd0是虚拟内存管理中负责换页的,当服务器内存不足的时候kswapd0会执行换页操作,这个换页操作是十分消耗主机cpu资源的。如果通过top发现该进程持续处于非睡眠状态,且运行时间较长,可以初步判定系统在持续的进行换页操作,可以将问题转向内存不足的原因来排查。
问题描述:
kswapd0 进程占用了系统大量 cpu 资源。
处理办法:
linux 系统通过分页机制管理内存的同时,将磁盘的一部分划出来作为虚拟内存。而 kswapd0 是 linux 系统虚拟内存管理中负责换页的进程。当系统内存不足时,kswapd0 会频繁的进行换页操作。而由于换页操作非常消耗 cpu 资源,所以会导致该进程持续占用较高 cpu 资源。
如果通过 top 等监控发现 kswapd0 进程持续处于非睡眠状态,且运行时间较长并持续占用较高 cpu 资源,则通常是由于系统在持续的进行换页操作所致。则可以通过 free 、ps 等指令进一步查询系统及系统内进程的内存占用情况,做进一步排查分析。
案例 :
1、使用top命令定位异常进程。可以看见12836的cpu和内存占用率都非常高
此时可以再执行ps -ef | grep java,查看所有的java进程,在结果中找到进程号为12836的进程,即可查看是哪个应用占用的该进程。
-
使用top -h -p 进程号查看异常线程
-
使用printf “%x\n” 线程号将异常线程号转化为16进制
-
使用jstack 进程号|grep 16进制异常线程号 -a90来定位异常代码的位置(最后的-a90是日志行数,也可以输出为文本文件或使用其他数字)。可以看到异常代码的位置。
2、cpu load 过高原因以及排查
造成cpu load过高的原因.从编程语言层次上full gc次数的增大或死循环都有可能造成cpu load 增高
具体的排查一句话描述就是
首先要找到哪几个线程在占用cpu,之后再通过线程的id值在堆栈文件中查找具体的线程
寻找最占cpu的进程
通过命令 ps ux
通过top -c命令显示进程运行信息列表 (按键p按cpu占有资源排序)
# ps ux
#top -c
top -c#效果
寻找最耗cpu的线程
top -hp 进程id 显示一个进程id的线程运行信息列表 (按键p按cpu占有资源排序)
如果该进程是java进程,需要具体查看是哪段代码造成的cpu负载过高,根据上述获得到的线程id可以使用jdk下的jstack来查看堆栈。
由于在堆栈中线程id是用16进制表示的,因此可以将上述线程转化成16进制的表示。
jstack java进程id | grep 16进制的线程id -c5 --color
3、服务器的cpu使用率特别高
排查思路:
-使用top或者mpstat查看cpu的使用情况
mpstat -p all 2 1
-top找出占用高的进程id
-查看进程占用线程数量,如java:
ps -elf|grep java|wc -l
1065
线上故障主要会包括cpu、磁盘、内存以及网络问题,而大多数故障可能会包含不止一个层面的问题,所以进行排查时候尽量四个方面依次排查一遍。
同时例如 jstack、jmap 等工具也是不囿于一个方面的问题的,基本上出问题就是df、free、top 三连,然后依次jstack、jmap伺候,具体问题具体分析即可。
一般来讲我们首先会排查 cpu 方面的问题。cpu 异常往往还是比较好定位的。
原因包括业务逻辑问题(死循环)、频繁gc以及上下文切换过多。而最常见的往往是业务逻辑(或者框架逻辑)导致的,可以使用jstack来分析对应的堆栈情况。
使用 jstack 分析 cpu 问题
我们先用 ps 命令找到对应进程的pid(如果你有好几个目标进程,可以先用top看一下哪个占用比较高)。
接着用top -h -p pid来找到 cpu 使用率比较高的一些线程
top
然后将占用最高的 pid 转换为 16 进制printf ‘%x\n’ pid得到 nid
接着直接在 jstack 中找到相应的堆栈信息jstack pid |grep ‘nid’ -c5 –color
可以看到我们已经找到了 nid 为 0x42 的堆栈信息,接着只要仔细分析一番即可。
当然更常见的是我们对整个 jstack 文件进行分析,通常我们会比较关注 waiting 和 timed_waiting 的部分,blocked 就不用说了。我们可以使用命令
cat jstack.log | grep "java.lang.thread.state" | sort -nr | uniq -c
来对 jstack 的状态有一个整体的把握,如果 waiting 之类的特别多,那么多半是有问题啦。
当然我们还是会使用 jstack 来分析问题,但有时候我们可以先确定下 gc 是不是太频繁,使用jstat -gc pid 1000命令来对 gc 分代变化情况进行观察,1000 表示采样间隔(ms),s0c/s1c、s0u/s1u、ec/eu、oc/ou、mc/mu 分别代表两个 survivor 区、eden 区、老年代、元数据区的容量和使用量。
ygc/ygt、fgc/fgct、gct 则代表 younggc、fullgc 的耗时和次数以及总耗时。如果看到 gc 比较频繁,再针对 gc 方面做进一步分析,具体可以参考一下 gc 章节的描述。
针对频繁上下文问题,我们可以使用vmstat命令来进行查看
cs(context switch)一列则代表了上下文切换的次数。
如果我们希望对特定的 pid 进行监控那么可以使用 pidstat -w pid命令,cswch 和 nvcswch 表示自愿及非自愿切换。
磁盘问题和 cpu 一样是属于比较基础的。首先是磁盘空间方面,我们直接使用df -hl来查看文件系统状态
更多时候,磁盘问题还是性能上的问题。我们可以通过 iostat -d -k -x来进行分析
最后一列%util可以看到每块磁盘写入的程度,而rrqpm/s以及wrqm/s分别表示读写速度,一般就能帮助定位到具体哪块磁盘出现问题了。
另外我们还需要知道是哪个进程在进行读写,一般来说开发自己心里有数,或者用 iotop 命令来进行定位文件读写的来源。
不过这边拿到的是 tid,我们要转换成 pid,可以通过 readlink 来找到 pidreadlink -f /proc/*/task/tid/…/…。
找到 pid 之后就可以看这个进程具体的读写情况cat /proc/pid/io
我们还可以通过 lsof 命令来确定具体的文件读写情况 lsof -p pid
内存问题排查起来相对比 cpu 麻烦一些,场景也比较多。主要包括 oom、gc 问题和堆外内存。一般来讲,我们会先用 free 命令先来检查一发内存的各种情况。
堆内内存
内存问题大多还都是堆内内存问题。表象上主要分为 oom 和 stack overflow。
oom
jmv 中的内存不足,oom 大致可以分为以下几种:
exception in thread “main” java.lang.outofmemoryerror: unable to create new native thread
这个意思是没有足够的内存空间给线程分配 java 栈,基本上还是线程池代码写的有问题,比如说忘记 shutdown,所以说应该首先从代码层面来寻找问题,使用 jstack 或者 jmap。如果一切都正常,jvm 方面可以通过指定xss来减少单个 thread stack 的大小。另外也可以在系统层面,可以通过修改/etc/security/limits.confnofile 和 nproc 来增大 os 对线程的限制。
exception in thread “main” java.lang.outofmemoryerror: java heap space
这个意思是堆的内存占用已经达到-xmx 设置的最大值,应该是最常见的 oom 错误了。解决思路仍然是先应该在代码中找,怀疑存在内存泄漏,通过 jstack 和 jmap 去定位问题。如果说一切都正常,才需要通过调整xmx的值来扩大内存。
caused by: java.lang.outofmemoryerror: meta space
这个意思是元数据区的内存占用已经达到xx:maxmetaspacesize设置的最大值,排查思路和上面的一致,参数方面可以通过xx:maxpermsize来进行调整(这里就不说 1.8 以前的永久代了)。
stack overflow
栈内存溢出,这个大家见到也比较多。
exception in thread “main” java.lang.stackoverflowerror
表示线程栈需要的内存大于 xss 值,同样也是先进行排查,参数方面通过xss来调整,但调整的太大可能又会引起 oom。
使用 jmap 定位代码内存泄漏
上述关于 oom 和 stack overflow 的代码排查方面,我们一般使用 jmapjmap -dump:format=b,file=filename pid来导出 dump 文件
通过 mat(eclipse memory analysis tools)导入 dump 文件进行分析,内存泄漏问题一般我们直接选 leak suspects 即可,mat 给出了内存泄漏的建议。另外也可以选择 top consumers 来查看最大对象报告。
和线程相关的问题可以选择 thread overview 进行分析。除此之外就是选择 histogram 类概览来自己慢慢分析,大家可以搜搜 mat 的相关教程。