2017-08-06 70 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对此有很好的支持),确定保留内存的类链非常容易。