V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
coderstory
V2EX  ›  Kubernetes

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

  •  
  •   coderstory · 2023-09-05 09:20:12 +08:00 · 2080 次点击
    这是一个创建于 430 天前的主题,其中的信息可能已经有所发展或是发生改变。

    项目上基于 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 条回复    2023-09-05 12:39:16 +08:00
    812603834
        1
    812603834  
       2023-09-05 09:31:25 +08:00
    内存占用缓慢上升是内存泄露了吧,dump 看看是啥占用了内存没释放?
    cheng6563
        2
    cheng6563  
       2023-09-05 09:34:04 +08:00
    Hostpot JVM 就是这样的,就算内部内存 GC 回收了,也很不喜欢把内存还给操作系统,换高版本的 JVM 或者设置一些 OPTS 会好一点。

    或者用 OpenJ9 JVM ,可以节省大量内存。
    Frankcox
        3
    Frankcox  
       2023-09-05 09:36:21 +08:00
    k8s 你在容器中直接跑 top 看的是带有宿主机的情况,试试 kubectl top 或者别的方法
    chendy
        4
    chendy  
       2023-09-05 09:41:57 +08:00
    加参数限制一下堆大小
    Xms Xmx alwaysPreTouch urandom 基本是必要的参数了吧
    tangAtang
        5
    tangAtang  
       2023-09-05 09:46:30 +08:00
    插眼,学习。我之前也遇到了,是因为 ohc 堆外内存占用,这个内存占用是不受 jvm 控制的
    coderstory
        6
    coderstory  
    OP
       2023-09-05 09:55:38 +08:00
    @Frankcox 我是看 java 进程的内存占用
    Citrus
        7
    Citrus  
       2023-09-05 10:33:05 +08:00
    插眼,学习。之前遇到的是文件系统缓存导致的统计问题,但是跟楼主这个好像不太一样。
    cdlnls
        8
    cdlnls  
       2023-09-05 10:46:39 +08:00
    在容器里面 jmap -heap <pid> 看看呢?一般要设置一下 Xmx 或者 MaxRAMPercentage 的吧
    mawerss1
        9
    mawerss1  
       2023-09-05 10:49:34 +08:00
    是否设置了 Xmx?
    Belmode
        10
    Belmode  
       2023-09-05 11:09:07 +08:00
    问了一下 GPT ,他说两者统计的内存不同。jprofile 只统计虚拟机进程关联的虚拟内存,而 top 统计所有进程关联的物理和虚拟内存
    tnhmcm
        11
    tnhmcm  
       2023-09-05 11:15:00 +08:00 via Android
    我也遇到过这种情况,容器内存一直涨直至重启,后来发现是 groovy 动态类没做缓存导致元空间的内存泄露。这种情况最好 dump 一下看看。
    julyclyde
        12
    julyclyde  
       2023-09-05 11:45:24 +08:00
    其实是好几个问题:
    JVM 内部的内存统计
    JVM 进程在操作系统内的内存统计( JVM 没归还给操作系统)
    容器的总内存量(因为 procfs 不是 cgroup aware 的,导致看到宿主机的总内存量而不是容器的)
    Foxkeh
        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
    cdlnls
        14
    cdlnls  
       2023-09-05 12:39:16 +08:00   ❤️ 2
    @Foxkeh 前几个月同样也处理了这个问题。补充一下,jdk8 中使用 UseContainerSupport + MaxRAMPercentage 一样也会有问题,现在的 jdk8 版本还只支持 cgroup v1 ,然后现在 k8s 基本上都是默认使用 cgroup v2 / systemd ,所以也会有问题。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1934 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 25ms · UTC 16:18 · PVG 00:18 · LAX 08:18 · JFK 11:18
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.