Apache Storm工作者内存泄漏 - 外部堆

时间:2015-03-25 07:44:46

标签: java memory memory-leaks garbage-collection apache-storm

我有一个4节点风暴群集。 Worker JVM参数如下:

-Xms5g -Xmx15g -XX:+UseG1GC -XX:MaxDirectMemorySize=1024m

风暴版:0.9.3

问题是:当进程内存达到14 + GB时,工作人员往往会显着减速。

在捕捉时我的顶部输出如下。

 PID USER      PR  NI    VIRT    RES    SHR S  %CPU %MEM     TIME+ COMMAND                                                                                                                                
 2075 root      20   0 18.132g 8.372g  12368 S  57.2 28.3  18:27.44 java 

GC日志:

3317.095: [GC pause (young), 0.1861930 secs]
   [Parallel Time: 180.9 ms, GC Workers: 4]
      [GC Worker Start (ms): Min: 3317095.5, Avg: 3317095.5, Max: 3317095.5, Diff: 0.0]
      [Ext Root Scanning (ms): Min: 29.0, Avg: 29.4, Max: 29.7, Diff: 0.7, Sum: 117.4]
      [Update RS (ms): Min: 18.0, Avg: 18.1, Max: 18.3, Diff: 0.3, Sum: 72.5]
         [Processed Buffers: Min: 31, Avg: 41.2, Max: 53, Diff: 22, Sum: 165]
      [Scan RS (ms): Min: 0.6, Avg: 0.7, Max: 0.8, Diff: 0.2, Sum: 2.8]
      [Code Root Scanning (ms): Min: 0.1, Avg: 0.1, Max: 0.1, Diff: 0.1, Sum: 0.4]
      [Object Copy (ms): Min: 132.1, Avg: 132.5, Max: 132.7, Diff: 0.6, Sum: 529.8]
      [Termination (ms): Min: 0.0, Avg: 0.0, Max: 0.0, Diff: 0.0, Sum: 0.0]
      [GC Worker Other (ms): Min: 0.0, Avg: 0.0, Max: 0.1, Diff: 0.0, Sum: 0.2]
      [GC Worker Total (ms): Min: 180.7, Avg: 180.8, Max: 180.8, Diff: 0.1, Sum: 723.1]
      [GC Worker End (ms): Min: 3317276.3, Avg: 3317276.3, Max: 3317276.3, Diff: 0.0]
   [Code Root Fixup: 0.1 ms]
   [Code Root Migration: 0.2 ms]
   [Clear CT: 0.4 ms]
   [Other: 4.6 ms]
      [Choose CSet: 0.0 ms]
      [Ref Proc: 1.4 ms]
      [Ref Enq: 0.1 ms]
      [Free CSet: 1.5 ms]
   [Eden: 2366.0M(2366.0M)->0.0B(1808.0M) Survivors: 94.0M->106.0M Heap: 5052.0M(15.0G)->2698.0M(15.0G)]
 [Times: user=0.73 sys=0.00, real=0.19 secs] 

我看到只使用了2698 MB的堆。但Linux Top显示RES内存为8.372g。当Top存储器达到~15GB时,该过程将开始堵塞,我想避免。

此外,我使用XX:MaxDirectMemorySize缩小了直接内存被某些外部API阻塞的可能性。

由于堆大小很大 - 如果我尝试使用分析器(在我的情况下是yourkit)来获取内存快照,则工作程序会崩溃。

我需要找到内存堵塞的来源。

另外,为了避免过多的消息,我使用TOPOLOGY_MAX_SPOUT_PENDING等于5来限制拓扑。

我正在使用KafkaSpout - 来自/net/wurstmeister/storm/storm-kafka-0.8-plus /

的storm.kafka.KafkaSpout

此外,我提到这个线程有类似的问题,但使用ZMQ而不是在较新版本的Storm中使用的Netty。

Spout memory leak

更新:当我删除所有螺栓并仅运行kafkaspout时,延迟时间最短,也没有内存问题。所以,大概我们可以怀疑加工螺栓。

1 个答案:

答案 0 :(得分:1)

解决。 实际上问题是G1的足迹对于过程记忆来说很大,但是收集更加优化。

从ParallelOldGC或CMS收集器到G1时,较大的JVM进程大小主要与“记帐”数据结构(如记忆集和集合集)相关。

记住集或RSet跟踪对象引用到给定区域。堆中每个区域有一个RSet。 RSet支持并行和独立收集区域。 RSets的总体足迹影响小于5%。

Collection设置或CSets将在GC中收集的区域集。在GC期间,CSet中的所有实时数据都被撤离(复制/移动)。区域集可以是伊甸园,幸存者和/或老一代。 CSets对JVM的大小影响不到1%。