原创 吴就业 125 0 2022-04-17
本文为博主原创文章,未经博主允许不得转载。
本文链接:https://wujiuye.com/article/67f23762f8b64a5ca49202c21b64b6f2
作者:吴就业
链接:https://wujiuye.com/article/67f23762f8b64a5ca49202c21b64b6f2
来源:吴就业的网络日记
本文为博主原创文章,未经博主允许不得转载。
本篇文章写于2022年04月17日,从公众号|掘金|CSDN手工同步过来(博客搬家),本篇为原创文章。
对于线上应用,出现进程自动挂掉的原因,如果可以排除因程序本身原因,那么很大可能性是因为操作系统内存不够用,进程被操作系统kill掉了。
那如何确认是否是被操作系统kill掉的呢?
如果是因OutOfMemory被系统kill掉的进程,会在/var/log目录下的dmesg文件中留下最终的遗迹。可使用dmesg命令查看操作系统kill进程日记。
dmesg -T | grep -E -i -B100 'killed process'
命令行执行输出如下(go进程)。
......
Out of memory: Kill process 28670 (bfe) score 386 or sacrifice child
Killed process 28670, UID 555, (bfe) total-vm:8478620kB, anon-rss:6149940kB, file-rss:4kB
如果能知道挂掉的进程id,且在dmesg命令输出文本中找到,就能知道是否因内存原因被操作系统kill掉。
如果是虚拟机部署,建议在启动脚本中输出进程的id到文件存储,以便于后续问题排查。
此方法同样可以用于容器排查。
由于kubernetes的最小调度单元是Pod,如果只是容器重启,Pod不变,所在的物理机(虚拟机)就不变。而dmesg输出的是物理机(虚拟机)的操作系统kill进程日记,因此,虽然容器重启了,但我们还能使用dmesg命令查看进程被kill的原因。但需要注意,进程ID与容器内看到的进程ID是不同的。
一个容器部署的Java进程因内存原因被系统kill掉的案例分析。
表格部分字段说明(我们关心的字段):
Killed process字段说明: * anon-rss(anonymous rss):匿名驻留集,比如malloc出来的就是匿名的。 * file-rss:映射到设备和文件上的内存页面。
图中所示案例,进程35566的rss值是522668,乘以4kb/页,结果与anon-rss值2071208kb接近,差不多2G,而容器的内存限制就是2G,因此可以确定是因为内存原因被kill掉了。
这通常是因为我们给进程配置的jvm堆内存大于给容器分配的最大可用内存导致的,或者是java进程使用了堆外内存,堆内存+堆外内存大于给容器分配的最大可用内存导致的。
声明:公众号、CSDN、掘金的曾用名:“Java艺术”,因此您可能看到一些早期的文章的图片有“Java艺术”的水印。
“编写一个Java Agent,这个Agent包的类不能跟应用程序的类冲突,所以我们需要自定义一个类加载器去加载我们Agent包里面的所有类,现在类冲突问题解决了,但是我Agent包也无法访问应用程序里面的类,这个问题怎么解?”
报错:no matching versions for query "v1.0"。依赖的module的版本号必须是"vx.x.x"的格式,其中'x.x.x'中的'x'是数字。
jeprof命令报错:`The first profile should be a remote form to use /pprof/symbol`,这是因为命令需要程序源文件(原二进制文件)。另外`FATAL ERROR: Did not specify profile file`错误也是一样的问题。
订阅
订阅新文章发布通知吧,不错过精彩内容!
输入邮箱,提交后我们会给您发送一封邮件,您需点击邮件中的链接完成订阅设置。