如何优化大内存的内存使用?

时间:2014-03-27 01:52:53

标签: java performance memory optimization map

我在java中有一个很大的HashMap,存储从String到Integer的映射。它有400K记录。它运行正常,但我想知道在内存使用方面是否有更好的优化。初始化Map后,只会搜索它,不会进行其他更新操作。

我依稀记得我遇到过将字符串键转换为int的一些建议,但不确定。请帮助或分享您的想法。

感谢。

4 个答案:

答案 0 :(得分:2)

  

我依稀记得我发现了一些将字符串键转换为int的建议,但不确定。

如果字符串键实际上是整数的字符串表示,那么使用Integer将它们转换为LongInteger.valueOf(String)个对象是有意义的。您将节省一些内存,因为原始包装类使用的内存少于相应的String对象。节省空间可能很大(可能约为16个字节,而每个键约为40个字节......取决于您的平台。)

另一方面,在进行hashmap查找之前,您需要将候选键从String转换为实际键类型。这种转换需要一些时间,通常会产生一些垃圾。


但是如果String键不表示整数,那么这根本不起作用。 (或者至少......我不知道你指的是什么“转换”......)

另请注意,密钥类型必须为Integer / Long,而不是int / long。通用类型参数必须是引用类型。


可能有第三方集合实现也有帮助......具体取决于您的数据结构的工作原理;例如Trove,Guava,Fastutil。尝试然后与String - >组合整数预转换...


关于使用数据库的建议。如果

  • 您不需要数据库的查询/更新/事务功能,AND
  • 您可以负担内存以将数据保存在内存中,并且
  • 您可以承担将数据加载到内存中的启动成本,

然后使用数据库对每次查找都是一个很大的,不必要的性能影响。

答案 1 :(得分:1)

您可能希望调整initialCapacityloadFactor以改善hashCode()以避免发生冲突,如果您希望以更高的速率阅读,如果您有太多的写入,则可能需要进行基准测试{{ 1}},

即使这对你的应用程序来说太大了,你也可以考虑将它从jvm的一边移到某个缓存(redis),或者如果你能承受很小的读/写延迟,可能是数据库

答案 2 :(得分:1)

如果数据太大,将数据写入数据库最终是最佳解决方案,但400k仍然可以在内存中使用。

但是,Java的内置HashMap实现使用单独的链接,并且每个键值对都有一个单独的类。通过构建Map的二次探测实现,我获得了很大(30%)的速度提升和令人敬畏的(50%)内存改进。

我建议你在网上搜索一下。有很多很好的实现!

答案 3 :(得分:0)

您可以使用Guava's ImmutableMap - 它针对一次性写入数据进行了优化,并采用~15% less memory than HashMap