1

我正在填满 JVM 堆空间。

更改参数以向 JVM 提供更多堆空间,或更改代码中算法中的某些内容以不使用太多空间是最推荐的两个选项。

但是,如果这两个已经被尝试和应用过,并且我仍然会出现内存不足的异常,我想看看其他选项是什么。

我发现了这个“使用内存映射文件来处理巨大的矩阵”的例子和一个名为HugeCollections的库,这是解决我的问题的一种有趣的方法。不幸的是,这个库已经一年多没有更新了,而且它不在任何 Maven 存储库中——所以对我来说它不是一个真正可靠的库。

我的问题是,是否有任何其他库这样做,或者实现它的好方法(具有集合对象(列表和集合)内存映射)?

4

4 回答 4

6

你不说你正在使用什么类型的集合,或者你使用它们的方式,所以很难给出建议。但是,请记住以下几点:

  • 将对象保存在 Java 堆上始终是最简单的选择,而且 RAM 相对便宜。
  • 盲目地移动到内存映射数据很可能会产生可怕的性能,尤其是当您在文件中移动和/或进行大量更改时。基于散列的集合类型是最差的,因为它们通过分发数据来工作。基于树的集合类型通常是更好的选择,线性集合可以双向使用。
  • 一旦移出堆外,您需要一种将对象与 Java 相互转换的方法。对象序列化是最简单的,但会增加很多开销。通过字节缓冲区访问的二进制对象通常是更好的选择,但您需要具有线程意识。
  • 您还必须为堆外对象管理自己的垃圾收集。如果您所做的只是创建/更新,这不是问题,但如果您要删除,很快就会变得很痛苦。
  • 如果您有大量数据,并且需要以各种方式访问​​这些数据,那么数据库可能是您最好的选择。
于 2012-10-09T15:05:10.887 回答
3

Unluckily, the library hasn't seen an update for over a year, and it's not in any Maven repo - so for me it's not a really reliable one我同意并写了。;)

我建议你看看https://github.com/peter-lawrey/Java-Chronicle已经使用了更高的性能。它确实是为 List & Queue 设计的,但您可以将它用于带有其他数据结构的 Map 或 Set。

根据您的要求,您可以编写自己的库。例如,对于时间序列数据,我编写了一个不同的库,不幸的是它不是开源的,但可以非常干净地加载 500+ GB 的表。

它不在任何 Maven 存储库中

这也不是,但会很高兴有人添加它。

于 2012-10-09T13:55:11.517 回答
1

听起来您要么遇到内存泄漏问题,要么试图将太大的对象放入内存。

您是否尝试过粗略估计加载数据所需的内存量?

于 2012-10-09T13:24:44.327 回答
1

假设您没有内存泄漏或其他问题,并且确实需要大量存储空间而无法将其放入堆中(我认为这不太可能),您基本上只有一个选择:

不要把你的数据放在堆上。就那么简单。现在,您使用哪种方法将数据移出非常取决于您的要求(什么样的数据、更新频率以及实际更新的数量?)。

注意:您可以在 64 位 VM 上使用非常大的堆,并在必要时扩大操作系统的交换空间。粗暴地增加最大堆大小(即使这意味着大量交换)可能是最简单的解决方案。在您概述的情况下,我当然会首先尝试。

于 2012-10-09T13:32:17.550 回答