2013-10-23 44 views
6

我有一个服务将分配给它的所有调用分配到内存中,因为我们不想丢失数据,同时我们需要这个服务因任何外部依赖而失败(比如像DB) 。然后,这些分阶段的呼叫将被定期接收并在后台处理。当Java中的集合超出容量时会发生什么?

如果出于任何原因,如果呼叫过多而且内存不足,我们需要警惕。

所以,简单地说,这个问题是:我需要捕获或监视什么异常来通知我,当列表的添加由于资源不足而失败时?它会导致虚拟机本身出现OOM,还是会出现集合级限制?

如果没有收集级别的限制,您会如何建议我监控该服务的使用情况?目前,我们有堆使用情况和内存使用情况指标。那些够了吗?另外,JVM被配置为在OOM错误时终止(这是因为VM管理器然后重新启动它正在管理的任何进程)。

+0

在内存方面,你会得到一个OOME。如果你想限制元素进入一个集合,你必须自己实现。 – Cruncher

+0

我们应该首先避免这种情况,而应该使用一些基于文件的缓存。 –

+0

这似乎很容易测试。编写一个简单的应用程序,在无限循环中将项添加到集合中,并查看发生了什么。 – Eran

回答

4

抛出的异常是OutOfMemoryException。一旦你的集合吃掉了所有可用的堆空间,这个异常就可以在应用程序的任何部分抛出。

但是,如果您知道可能会针对特定集合抛出它,最好的方法可能是防止发生这种情况,即限制此集合或使用缓存,以便未使用的实体按需驱逐和重新加载。对于轻量级的缓存实现,我会推荐Guava的CacheBuilder

UPDATE

既然大家提出基于FS-存储,这里是我的轻量级下拉建议:

  • CacheBuilder从NoSQL的数据库加载序列化的数据
  • Kryo串行转换您的物体分成byte[]
  • MapDB存储(或任何其他嵌入式NoSQL解决方案哟你更喜欢)。
+0

迄今为止所有的答案都很棒,但唉。我只能选择一个。由于这篇文章总结了这一切,我将其标记为正确的。感谢您花时间! –

+0

谢谢,不客气! –

2

这是我在Collection.add的规范中:

如果一个集合拒绝添加特定的元素以外,它已经包含元素,它必须抛出一个异常任何原因(而比返回假)。这保留了该调用返回后集合始终包含指定元素的不变量。

它没有指定哪个异常,所以不同的集合可能会引发不同的异常。

+0

由于我们必须确保数据被添加或通知我们,这一点非常重要,所以这当然值得记住。 –

2

我认为让应用程序失败悲惨不是一个理想的设计选择。你应该在集合的大小上有个门槛,并决定在这种情况下做什么:在某处(磁盘?)刷新它,发送一个通知(JMX/email),抛出一个错误(或让OOME传播)。

这就是说,我会给你一个设计建议。从您对服务的简要描述和稍微晦涩的描述中,听起来对您而言,您需要一个工作队列来坐在您服务的以外的某个地方,例如,,JMS服务器甚至数据库。通过这种方式,即使您的服务因任何原因而死亡,您的后台进程也能够从队列(db)中提取请求并进行处理。

+0

完全有道理,绝对是正确的路要走。尽管我没有使用数据库,但我正在使用基于FS的存储(减缓外部依赖对于我们来说是一个更大的担忧,而不是丢失数据 - 我们没有发生数据丢失)。感谢您抽出宝贵的时间 –

相关问题