• (k8s中)docker netty OOM问题记录


    1、首先查看docker的内存占用情况:

    docker top 容器名 -u 查看内存cpu占用率(容器名来自kubectl describe pod xxx或者docker ps)
    在这里插入图片描述
    可以看出内存一直增长,作为IO代理这是不正常的。

    2、修改启动参数和配置文件

    需要注意的是为了安全考虑,docker默认是不能使用一些调试手段的,需要修改启动参数和yaml
    docker file中增加启动参数(yaml中应该也可以):

    ENTRYPOINT ["java", "-jar", "/usr/local/bin/access-1.0-SNAPSHOT.jar", "-XX:NativeMemoryTracking=detail"]
    
    • 1

    yaml增加:

    apiVersion: apps/v1
    kind: Deployment
    .......
    spec:
      ........
      template:
        ........
        spec:      
          containers:
            - name: access
              .........          
              securityContext:
                  capabilities:
                    add: ["SYS_PTRACE"]
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    3、查看具体内存占用

    各类内存增长情况:

    #建立内存基线
    jcmd 1 VM.native_memory baseline
    #与基线对比
    jcmd 1 VM.native_memory summary.diff
    
    • 1
    • 2
    • 3
    • 4

    其中1是pid,可以通过jps查看

    查看当前内存具体申请源:

    jcmd 1 VM.native_memory detail scale=MB  
    
    • 1

    查看结果是Other的内存增长比较明显:

    [0x00007f76b2143b77] Unsafe_AllocateMemory0+0x87
    [0x00007f769577c4ba]
                                 (malloc=732MB type=Other #228)
    
    • 1
    • 2
    • 3

    Unsafe_AllocateMemory0一般是ByteBuf申请的内存,jvm不管理,也就是不会gc,需要自己关注申请和释放

    4、自己申请的ByteBuf

    自己申请的ByteBuf要么往下传递(通过ctx write或者fire read)由后面的pipe节点释放,要么自己通过release释放。
    如果是写入服务器response中的content,通过ctx.writeAndFlush往下传递,由netty去管就行了。

    5、在pipe的handle中收到的msg

    比如服务器上收到的request,如果不是最后一个节点,则必须显式传递:ctx.fireChannelRead(msg);
    如果是最后一个节点则自己手动释放,可以content.release也可以ReferenceCountUtil.release(msg);
    也可以继承SimpleChannelInboundHandler,SimpleChannelInboundHandler中会释放,不用自己释放了。
    如果是服务器处理一个请求回复一个响应,一般是作为最后一个节点,可以继承SimpleChannelInboundHandler。

    6、netty的ByteBuf泄漏检测

    在intellij中测试,先增加vm参数-Dio.netty.leakDetection.level=paranoid -Dio.netty.leakDetection.samplingInterval=128(需要再Modify options中选择才会出现,注意不是Program arguments):
    在这里插入图片描述
    测试代码:

      public static void main(String[] args) {
        ByteBuf buf = PooledByteBufAllocator.DEFAULT.buffer(1024);
        buf = null;
        System.gc();        
        try {
            Thread.sleep(1000);
        // 再申请一次,此时会检测到泄漏并报告
        PooledByteBufAllocator.DEFAULT.buffer(1024*1024);   
        } catch (Exception e) {
            return;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    运行后会报告泄露:
    在这里插入图片描述

  • 相关阅读:
    基于Java+SpringBoot+Mybaties-plus+Vue+elememt + uniapp 新闻资讯 的设计与实现
    QGraphicsItem鼠标拖动旋转(五)
    常驻巨噬细胞诱导的纤维化在胰腺炎性损伤和PDAC中具有不同的作用
    MySQL(12):MySQL数据类型
    Java学习笔记 --- Collections工具类
    JVM内存和垃圾回收-05.虚拟机栈
    京东数据分析:2023年9月京东洗烘套装品牌销量排行榜!
    c# 输出二进制字符串
    Linux系统编程系列之线程的信号处理
    Head First设计模式(阅读笔记)-09.模板方法模式
  • 原文地址:https://blog.csdn.net/aashuii/article/details/136365312