LinkedHashMap内存消耗

7
用户上传一个由100万个单词组成的巨大文件。我解析文件并将文件的每一行放入LinkedHashMap<Integer, String>中。
我需要O(1)访问和删除键。此外,我需要保留访问顺序,从任何位置迭代和排序。
内存消耗巨大。我启用了Java 8中出现的Strings去重功能,但结果表明LinkedHashMap消耗了大部分内存。
我发现LinkedHashMap.Entry 消耗40字节,但只有两个指针-一个用于下一个条目,一个用于上一个条目。我认为1个指针应该是64位或32位。但如果我将409,405,320(字节)除以6,823,422(条目数),我得到每个条目60字节。

我认为我不需要前一个指针,只有下一个指针就足以保持顺序。为什么LinkedHashMap会消耗这么多内存?如何减少内存消耗?

Instance occurence


Integer包装器使用了那么多额外的内存吗?也许一个基于int的实现可以帮助。参考:https://github.com/ggrandes/kvstore/blob/master/src/main/java/org/javastack/kvstore/structures/hash/IntLinkedHashMap.java - Salem
1
如果您查看图片,就会发现 Integer 占用了堆的 16%。而 LinkedHashMap.Entry 则占用了超过 3 倍。我认为 OP 想知道为什么会出现这种情况。 - Michael
1
当您浏览源代码时,速度太快了。该条目继承自HashMap.Node,它还有4个字段,并且还有其他对象头,其大小只是实现细节。 - glee8e
我进行了一项小测试,我的输入占用了40个字节 java.util.LinkedHashMap$Entry 240,034,920 (32.3%) 6,000,873 (24.5%)。也许你有一些内存泄漏:[(https://hoangx281283.wordpress.com/2012/11/18/wrong-use-of-linkedhashmap-causes-memory-leak/] (https://hoangx281283.wordpress.com/2012/11/18/wrong-use-of-linkedhashmap-causes-memory-leak/) - Planck Constant
1个回答

1
如何减少内存消耗?
1)在JVM启动时添加-XX:+UseCompressedOops标志。
2)为您的需求优化自己的LinkedHashMap版本。例如,使用原始int作为键,而不是Integer,如果您不需要它,则删除“previous”指针等。请注意,除非您希望在GPLv2许可下发布修改后的哈希映射实现,否则可能无法复制OpenJDK源代码。但是,您可以从Android开源项目中复制和修改LinkedHashMap实现,因为它是Apache许可。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接