美文网首页工作生活
某游戏海外版本堆外内存泄露排查

某游戏海外版本堆外内存泄露排查

作者: landon30 | 来源:发表于2019-06-29 17:40 被阅读0次

    某游戏海外版本堆外内存泄露排查

    1. 现象

      • 线上有部分服务器用top发现Java进程内存占用占比达到99,而且出现了有一个服务器被Linux OOM Kill
    2. 排查

      • 选择了110服,该机器的Java进程最大堆内存设置的是9710m,但是进程占用的RES却达到了14g,远比堆内存大很多,所以初步确认,一定是出现了堆外内存泄露
    3. 工具安装

      • 堆外内存泄露的工具通常是gperftools

      • 同时要安装libunwind

        1. libunwind默认安装在/usr/local/lib
        2. 需要root在/etc/ld.so.conf.d建一个usr_local_lib.conf,文件内容是/usr/local/lib/
        3. 然后使用ldconfig命令刷一下
        
      • java进程启动脚本增加参数

        export LD_PRELOAD=/usr/local/lib/libtcmalloc.so
        export HEAPPROFILE=/tmp/nonheapleak
        
      • 注:

    4. 定位

      • 启动后,在/tmp目录会每隔一段时间都会生成如nonheapleak_31733.0088.heap、nonheapleak_31733.0089.heap等文件

      • 使用如下命令分析

        $ pprof --text ~/kof/usr/jdk/bin/java nonheapleak_31733.0089.heap | less

      • 输出

        Using local file /opt/home/service/kof/usr/jdk/bin/java.
        Using local file nonheapleak_31733.0089.heap.
        Total: 1509.3 MB
          1293.1  85.7%  85.7%   1293.1  85.7% luaM_realloc_
           179.4  11.9%  97.6%    179.4  11.9% os::malloc
            30.0   2.0%  99.5%     30.0   2.0% init
             2.4   0.2%  99.7%      2.4   0.2% updatewindow
             1.2   0.1%  99.8%      1.2   0.1% strbuf_resize
             1.2   0.1%  99.9%      1.2   0.1% ObjectSynchronizer::omAlloc
             1.0   0.1%  99.9%      1.0   0.1% inflateInit2_
        
      • 从上面可以看到luaM_realloc_占用了较大内存,初步判断堆外内存占用这块主要是lua

      • 所以下面的排查和解决思路是

        为什么lua占用了这么大的内存

        是否有泄露的可能

        需要客户端同学一起排查,一个gc后的luastate到底内存都有哪些对象

        是否关闭本地复盘,因为有潜在的oom-kill的风险

    5. 其他

      • -XX:MaxDirectMemorySize=size用于设置New I/O(java.nio) direct-buffer allocations的最大大小,即这个主要是nio相关,即狭义的‘堆外内存’。而Direct ByteBuffer分配出去的直接内存其实也是由GC负责回收的
      • 而本例是指jni分配的内存导致的内存泄露,这个是无法被jvm回收的
    6. ref

    相关文章

      网友评论

        本文标题:某游戏海外版本堆外内存泄露排查

        本文链接:https://www.haomeiwen.com/subject/nqnpcctx.html