Java 哈泽尔被遗忘了

Java 哈泽尔被遗忘了,java,caching,hazelcast,hazelcast-imap,Java,Caching,Hazelcast,Hazelcast Imap,我们有一个Java应用程序,每分钟处理10万个包。这些包包括用户操作详细信息和一个用户操作的详细信息。一次操作可以有3到14个包。所有收到的包都包含操作的唯一数据,不幸的是操作没有id。因此,我们使用用户id和操作日期合并属于同一操作的包。我们保证,我们将在最多15分钟内收到用户操作的所有包。因此,为了在持久化之前合并所有包,我们将在Hazelcast上缓存所有收到的包,并在收到OPSTART或OPEND包时插入包。这些包裹在20分钟后过期。但是,运行1小时左右后,Hazelcast堆空间超过7

我们有一个Java应用程序,每分钟处理10万个包。这些包包括用户操作详细信息和一个用户操作的详细信息。一次操作可以有3到14个包。所有收到的包都包含操作的唯一数据,不幸的是操作没有id。因此,我们使用用户id和操作日期合并属于同一操作的包。我们保证,我们将在最多15分钟内收到用户操作的所有包。因此,为了在持久化之前合并所有包,我们将在Hazelcast上缓存所有收到的包,并在收到OPSTART或OPEND包时插入包。这些包裹在20分钟后过期。但是,运行1小时左右后,Hazelcast堆空间超过70%

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
大约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抛出内存不足异常的原因。原因可能是什么?我们可以做些什么来了解问题?

确定OOME原因的最佳方法是进行堆转储并进行分析,查看内存是如何保留的。可能会有大量字节数组。如果您检查对这些字节数组的传入引用并聚合它们(jprofiler对此有很好的支持),就很容易确定保留内存的类链

如果你说4GB应该足够了,你是如何计算需求的?你看过headdump了吗?听起来“expire”过程并没有逐出包。或者其他类型的内存泄漏。