我们有包含树型结构、ArrayList和MultiMaps等大型对象的Java程序。
我遇到的问题是,我们已经分配了3 3GB的堆内存,但它仍然没有空间。
我想知道在座的任何人是否可以建议一种方法,将这些对象存储在堆之外,并根据需要将数据块读回java程序,以供每个处理调用使用。我感兴趣的是将它们存储在文件中,而不是出于其他原因而不是数据库。
我偶然发现了“内存映射文件”,有人在一个相关的问题上建议了“协议缓冲区”,这些对我来说都是陌生的概念,我想知道是否有一个简单的方法。我也找不到这两个概念的好例子。
会非常感谢你的帮助。
性能是非常重要的考虑因素,我知道JVM堆分配,但我不希望增加JVM堆大小。
发布于 2014-09-05 04:09:04
您可以考虑将数据存储在Chronicle Map之类的文件中。这使用了堆外内存,可以在不产生任何垃圾的情况下进行存储和访问。这允许您减少堆大小,但您仍然需要购买合理的内存。我建议您考虑至少拥有32 GB的内存,无论您是在堆上还是在堆外使用较大的数据集。
我没有理由非得去寻找奇特的解决方案
在这种情况下,请坚持使用堆上解决方案。你可以花大约200美元买到16 GB的内存。
我不想增加
堆的大小。
问问你自己,你愿意投入多少时间/金钱来避免增加堆积。你当然可以这样做,但是为了节省4 GB,我不会在这上面花一天的时间。节省40 GB、400 GB或4 TB则是另一回事。
发布于 2014-09-06 07:00:38
Protocol Buffers不能很好地处理内存映射文件,因为该文件包含编码数据,必须先对其进行解码才能使用它。此解码步骤生成堆对象。但是,如果不小心,您可能会浪费大量时间重复解码相同的数据。
Cap'n Proto是一种较新的格式,它非常类似于协议缓冲区,但明确地设计为使用内存映射文件。盘上格式被设计成可以在没有解码步骤的情况下就地使用。我们正在开发一款Java version,应该在几周内就能投入生产使用。
(披露:我是Cap的创建者,也曾是Google的Protocol Buffers的维护者。)
发布于 2014-09-05 10:01:54
您可以使用Guava中的不可变集合,它们通常不会占用太多内存。
如果字符串占用了你相当一部分的内存,你也许可以使用String.intern。
如果你有很多盒装的原语,你可以使用trove4j节省很多钱。
您可能会使用一些小技巧,如使用较小的数据类型等。
但你真的应该让你的办公室获得更多的内存,而不是浪费你的时间在拥有与智能手机一样大的RAM的计算机上!
https://stackoverflow.com/questions/25673536
复制相似问题