coderstory

有个服务在 k8s 中运行, top 命令查看到的内存使用和 jprofile 查看到的差异非常大

  •  
  •   coderstory · Sep 5, 2023 · 3693 views
    This topic created in 1155 days ago, the information mentioned may be changed or developed.

    项目上基于 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

    14 replies  •  2023-09-05 12:39:16 +08:00
    libraaaa
    libraaaa
    Sep 5, 2023
    1
    内存占用缓慢上升是内存泄露了吧,dump 看看是啥占用了内存没释放?
    cheng6563
    cheng6563
    Sep 5, 2023
    2
    Hostpot JVM 就是这样的,就算内部内存 GC 回收了,也很不喜欢把内存还给操作系统,换高版本的 JVM 或者设置一些 OPTS 会好一点。

    或者用 OpenJ9 JVM ,可以节省大量内存。
    Frankcox
    Frankcox
    Sep 5, 2023
    3
    k8s 你在容器中直接跑 top 看的是带有宿主机的情况,试试 kubectl top 或者别的方法
    chendy
    chendy
    Sep 5, 2023
    4
    加参数限制一下堆大小
    Xms Xmx alwaysPreTouch urandom 基本是必要的参数了吧
    tangAtang
    tangAtang
    Sep 5, 2023
    5
    插眼,学习。我之前也遇到了,是因为 ohc 堆外内存占用,这个内存占用是不受 jvm 控制的
    coderstory
    coderstory
    OP
    Sep 5, 2023
    6
    @Frankcox 我是看 java 进程的内存占用
    Citrus
    Citrus
    Sep 5, 2023
    7
    插眼,学习。之前遇到的是文件系统缓存导致的统计问题,但是跟楼主这个好像不太一样。
    cctv6
    cctv6
    Sep 5, 2023
    8
    在容器里面 jmap -heap <pid> 看看呢?一般要设置一下 Xmx 或者 MaxRAMPercentage 的吧
    mawerss1
    mawerss1
    Sep 5, 2023
    9
    是否设置了 Xmx?
    Belmode
    Belmode
    Sep 5, 2023
    10
    问了一下 GPT ,他说两者统计的内存不同。jprofile 只统计虚拟机进程关联的虚拟内存,而 top 统计所有进程关联的物理和虚拟内存
    tnhmcm
    tnhmcm
    Sep 5, 2023 via Android
    11
    我也遇到过这种情况,容器内存一直涨直至重启,后来发现是 groovy 动态类没做缓存导致元空间的内存泄露。这种情况最好 dump 一下看看。
    julyclyde
    julyclyde
    Sep 5, 2023
    12
    其实是好几个问题:
    JVM 内部的内存统计
    JVM 进程在操作系统内的内存统计( JVM 没归还给操作系统)
    容器的总内存量(因为 procfs 不是 cgroup aware 的,导致看到宿主机的总内存量而不是容器的)
    Foxkeh
    Foxkeh
    Sep 5, 2023❤️1
    13
    JDK 版本和启动参数是否合适?
    几个月前才处理了个类似的问题. 就是老版本 JDK 无法感知容器的内存限制. 不知是不是跟我一样的情况
    https://www.cnblogs.com/caoweixiong/p/12427202.html
    https://juejin.cn/post/7020287761949130759
    cctv6
    cctv6
    Sep 5, 2023❤️2
    14
    @Foxkeh 前几个月同样也处理了这个问题。补充一下,jdk8 中使用 UseContainerSupport + MaxRAMPercentage 一样也会有问题,现在的 jdk8 版本还只支持 cgroup v1 ,然后现在 k8s 基本上都是默认使用 cgroup v2 / systemd ,所以也会有问题。
    About   ·   Help   ·   Advertise   ·   Blog   ·   API   ·   FAQ   ·   Privacy   ·   Solana   ·   3209 Online   Highest 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 49ms · UTC 11:11 · PVG 19:11 · LAX 03:11 · JFK 06:11
    ♥ Do have faith in what you're doing.