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

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

作者: 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