侧边栏壁纸
博主头像
buukle博主等级

布壳儿

  • 累计撰写 106 篇文章
  • 累计创建 15 个标签
  • 累计收到 9 条评论

目 录CONTENT

文章目录

jdk(3) - jvm内存实战

administrator
2021-06-18 / 0 评论 / 0 点赞 / 342 阅读 / 2175 字

软件环境

1G 1U 阿里云ECS 服务器, 集中部署 buukle-cms , buukle-gateway , buukle-www 三个项目.

现象

项目发布完, 正常访问一段时间后,buukle-gateway,buukle-cms随机出现宕机现象.

排查步骤

1. jvm监控

1.1 查看进程

ssh登录服务器,使用如下命令查看在运行的java进程:

 jps -m -l 

结果 :

b39ec1b800184c7f857935ca5f854743.png
前边是进程号,后边是应用名称 .

1.2 查看jvm堆内存情况

使用如下命令, 查看指定应用的堆内存分配情况 :

jmap -heap 进程号

结果 :
56ea68f5a4854e8a85bdb2f16ff6ac94.png
我们可以看到:
新生代(New Generation)占用了30.9375MB的内存,其中包括 Eden区和survivor区;新生代剩余 19.21MB;
永久代(tenured generation) 占用了68.56640625MB 内存,剩余 16.626MB;
内存使用正常,且比例符合G1收集器默认的内存分配比例,静态观察JVM没有发现问题;
然后通过java VisualVM 动态监控了一段时间同样也没有发现问题.
(java VisualVM 使用方法 : java VisualVM 远程监控(springboot-jar))
查看程序日志,也没有OOM异常,所以排除了JVM的问题.

1.3 怀疑是堆外内存作祟

查看系统日志,发现是系统内存不足, 操作系统将java进程杀掉了 .
我们好奇,一个java应用究竟占多少内存?
使用如下命令查看buukle-www应用所占内存:

top -p 进程号

结果 :
903deefd3c434a2f807688cfd83b63c6.png
一个springboot 服务大概占300M左右. 我们在之前看到, 其堆内存总共有 30.9375MB + 68.56640625MB = 100MB;
可知,堆外内存占用了 200MB左右的空间.

使用 free -h 查看系统内存信息 :

425aa1e4989d4e4296fe3c283c6b8aa8.png

我们发现,系统本身剩余991MB的内存, 而我同时部署了 buukle-www,buukle-cms,buukle-gateway 三个应用,没个应用大概占300MB左右内存. 当有访问进来时,系统堆外内存使用上升. 当并发请求过多,或者后台任务占用堆外内存过多, 超出了系统内存的容量, linux就会对当前最占用资源的进程进行kill,以保证系统的运行.

1.4 解决

暂时是在每次发布后手动 kill cms应用,cms需要在另外的服务器上部署.
其实也可以尝试通过设置linux swap分区,利用硬盘内存缓和一下内存需要, 但是会导致应用请求变慢,暂时未采用.

0
jdk
  1. qrcode alipay
  2. qrcode weixin

评论区