项目上基于 spring cloud 开发的一个标准微服务,在 k8s 中部署运行。目前发现各个服务的内存占用随着时间推移缓慢上升,直到超过 limit 被杀死重启。
所以我想看下运行了一个星期的服务内存使用为什么降不下来,手动 jcmd GC.run 也没啥效果。
在容器中运行 top 看到 java 集成的 RES 值为 1.9g 然后使用 jprofile 连接这个 java 集成,看到使用的堆和非堆内存使用总和都没到 1GB 我不清楚哪里操作错了
https://blog.coderstory.cn/wp-content/uploads/2023/09/1693876771-企业微信截图_16938763642675.png
https://blog.coderstory.cn/wp-content/uploads/2023/09/1693876770-企业微信截图_16938763293140.png
1
812603834 2023-09-05 09:31:25 +08:00
内存占用缓慢上升是内存泄露了吧,dump 看看是啥占用了内存没释放?
|
2
cheng6563 2023-09-05 09:34:04 +08:00
Hostpot JVM 就是这样的,就算内部内存 GC 回收了,也很不喜欢把内存还给操作系统,换高版本的 JVM 或者设置一些 OPTS 会好一点。
或者用 OpenJ9 JVM ,可以节省大量内存。 |
3
Frankcox 2023-09-05 09:36:21 +08:00
k8s 你在容器中直接跑 top 看的是带有宿主机的情况,试试 kubectl top 或者别的方法
|
4
chendy 2023-09-05 09:41:57 +08:00
加参数限制一下堆大小
Xms Xmx alwaysPreTouch urandom 基本是必要的参数了吧 |
5
tangAtang 2023-09-05 09:46:30 +08:00
插眼,学习。我之前也遇到了,是因为 ohc 堆外内存占用,这个内存占用是不受 jvm 控制的
|
6
coderstory OP @Frankcox 我是看 java 进程的内存占用
|
7
Citrus 2023-09-05 10:33:05 +08:00
插眼,学习。之前遇到的是文件系统缓存导致的统计问题,但是跟楼主这个好像不太一样。
|
8
cdlnls 2023-09-05 10:46:39 +08:00
在容器里面 jmap -heap <pid> 看看呢?一般要设置一下 Xmx 或者 MaxRAMPercentage 的吧
|
9
mawerss1 2023-09-05 10:49:34 +08:00
是否设置了 Xmx?
|
10
Belmode 2023-09-05 11:09:07 +08:00
问了一下 GPT ,他说两者统计的内存不同。jprofile 只统计虚拟机进程关联的虚拟内存,而 top 统计所有进程关联的物理和虚拟内存
|
11
tnhmcm 2023-09-05 11:15:00 +08:00 via Android
我也遇到过这种情况,容器内存一直涨直至重启,后来发现是 groovy 动态类没做缓存导致元空间的内存泄露。这种情况最好 dump 一下看看。
|
12
julyclyde 2023-09-05 11:45:24 +08:00
其实是好几个问题:
JVM 内部的内存统计 JVM 进程在操作系统内的内存统计( JVM 没归还给操作系统) 容器的总内存量(因为 procfs 不是 cgroup aware 的,导致看到宿主机的总内存量而不是容器的) |
13
Foxkeh 2023-09-05 12:19:15 +08:00 1
JDK 版本和启动参数是否合适?
几个月前才处理了个类似的问题. 就是老版本 JDK 无法感知容器的内存限制. 不知是不是跟我一样的情况 https://www.cnblogs.com/caoweixiong/p/12427202.html https://juejin.cn/post/7020287761949130759 |