2017-08-06 68 views
0

我們有一個每分鐘處理100k包的Java應用程序。這些軟件包包括用戶操作細節和一個用戶操作。一個操作可以有3到14個包。所有收到的軟件包都包含操作的唯一數據,不幸的是操作沒有ID。因此,我們使用用戶標識和操作日期來合併屬於相同操作的包。我們保證,我們將在15分鐘內收到用戶操作的所有包裹。因此,要在保存之前合併所有軟件包,我們會將所有收到的軟件包緩存到Hazelcast上,並在收到OPSTART或OPEND軟件包時插入軟件包。這些軟件包在20分鐘後過期。然而,運行1小時左右後,Hazelcast堆空間超過70%。Hazelcast內存不足

c.h.internal.diagnostics.HealthMonitor : [192.168.2.42]:5701 [dev] [3.7.5] processors=4, physical.memory.total=15.7G, physical.memory.free=6.1G, swap.space.total=2.0G, swap.space.free=2.0G, heap.memory.used=3.1G, heap.memory.free=267.1M, heap.memory.total=3.3G, heap.memory.max=3.5G, heap.memory.used/total=92.15%, heap.memory.used/max=88.02%, minor.gc.count=71, minor.gc.time=4628ms, major.gc.count=10, major.gc.time=7186ms, load.process=0.00%, load.system=0.01%, load.systemAverage=0.00%, thread.count=502, thread.peakCount=502, cluster.timeDiff=-121091, event.q.size=0, executor.q.async.size=0, executor.q.client.size=0, executor.q.query.size=0, executor.q.scheduled.size=0, executor.q.io.size=0, executor.q.system.size=0, executor.q.operations.size=0, executor.q.priorityOperation.size=0, operations.completed.count=4722977, executor.q.mapLoad.size=0, executor.q.mapLoadAllKeys.size=0, executor.q.cluster.size=0, executor.q.response.size=0, operations.running.count=0, operations.pending.invocations.percentage=0.00%, operations.pending.invocations.count=50, proxy.count=0, clientEndpoint.count=0, connection.active.count=1, client.connection.count=0, connection.count=1 

大約一個半小時後,調用開始超時。

c.h.s.i.o.impl.InvocationMonitor   : [192.168.2.42]:5701 [dev] [3.7.5] Invocations:50 timeouts:0 backup-timeouts:1 

從開始2-3小時後,Hazelcast拋出內存不足異常,部署失敗。

4GB的內存應該足夠用於緩存的數據。我們無法找到導致Hazelcast拋出內存異常的原因。可能是什麼原因?我們能做些什麼來理解這個問題?

+0

如果你說4GB應該夠了,你是如何計算需求的?你看到了一個頭轉儲嗎? – noctarius

+0

聽起來像「過期」過程不是驅逐包。這或者其他一些內存泄漏。 – rghome

回答

1

確定OOME原因的最佳方法是創建一個堆轉儲並對其進行分析並查看內存是如何保留的。可能它會是大量的字節數組。如果你檢查這些字節數組的傳入引用並對它們進行聚合(jprofiler對此有很好的支持),確定保留內存的類鏈非常容易。