7

我的 Java 应用程序维护一个内部缓存,可以增长到 10 个演出。过期策略设置为 30 分钟或达到内存阈值时(我使用的是本地 ehcache)。很明显,30 分钟后,所有缓存的对象都将在旧 gen 中,并且需要完整的 gc 来收集它们。至于现在停止世界暂停可以达到 6 秒,我想减少它。

平均对象大小为 500k,但可能高达 1 meg,因此我们谈论的是 10000-20000 个缓存对象(实际上是字节数组)。

GC 优化的最佳策略是什么?我知道我可以脱离堆,但这是一种不得已的解决方案。

谢谢!

4

2 回答 2

5

10GB 缓存不是你应该在堆中做的事情。使用ByteBuffers进行缓存。对象创建不应该那么昂贵。这种方式不涉及 GC,您可以自己管理所有内容。

例如,如果您在 Java 数据库管理系统中实现页面缓存,您将不会为它创建对象,而是使用字节缓冲区或托管字节缓冲区或最佳直接字节缓冲区。您可以在此处了解有关这三个方面的更多信息。

如果您处理更多,那么假设一次有一百万个对象,您将看到 GC 时间份额上升。我看到我们管理大量节点进行数据处理的情况,这真的很慢。然后我们切换到直接字节缓冲区方案,甚至使用了一些额外的技术,我们能够在其中容纳更多数据(每个对象至少需要 24 个字节)并且首先停止考虑对象。最后我们处理的是数据而不是对象。这将性能提高了很多倍,并且我们能够处理比我们预期的更多的数据。

之后我们注意到它都适合一个数据库,这就是我们刮掉所有东西的重点。

因此,请查看直接缓冲区可以为您做什么。

于 2013-10-07T18:55:33.773 回答
2

我经常使用在 JVM 堆中保存 10-30 GiB 数据的缓存服务。Concurent Mark Sweep (GC) 算法可以很好地处理这些情况,将最大 Stop-the-World 暂停时间保持在 100 毫秒左右(不过,绝对数字取决于硬件)。

您可以在我的博客中找到缓存应用程序和堆大小的 GC 调整检查列表

在这里,您可以找到更多关于 Concurent Mark Sweep 算法本身的信息。

于 2013-10-08T04:13:25.277 回答