HashMap内存效率

时间:2014-02-10 00:55:12

标签: java memory-management collections hashmap

我正在开发一个Java Web应用程序,它使用一个大型级联的哈希映射,如下所示:

HashMap<String, HashMap<String, HashMap<String, Double[]>>>

构造一旦创建,然后以只读方式使用。

double数组总是有两个元素。我遇到的问题是,最后我每个双数组使用超过160个字节。这是两个双打使用的10倍(每个8字节)。

我使用Runtime.getRuntime().totalMemory()在创建地图之前查看一次内存使用情况,并在执行这些测量之后查看内存使用情况。

如何最小化内存开销?

我现在考虑三种可能的解决方案:

  • 使用其他数据结构或hashmap实现(?)

  • 完全预先计算每张地图的大小,并将初始容量设置为此数字+ 1,并将加载因子设置为1.0。

  • 通过附加所有键将其折叠为一个字符串。这对我来说不太实用,但绝对可行。但代码看起来很糟糕。

现在我的问题是,在我创建一次哈希映射然后只将它们用于只读的情况下,最小化hashmap内存开销的最佳方法是什么?

4 个答案:

答案 0 :(得分:2)

你的描述有点困惑,但我会:

  1. 使用非常高的负载系数,例如95%。

  2. 将其设为double[]而不是Double[]

答案 1 :(得分:1)

如果您在调用get()时知道所有密钥,那么我建议为密钥创建一个新对象。请务必实施equals()hashCode()

修改

在连接上使用对象将防止与certian组合发生密钥冲突。 如果字符串是“AA”,“BB”和“CC”,并且连接到“AABBCC”,那么“A”,“AB和”BCC“将连接到相同的值”AABBCC“。此外它更多可读代码。

我过去肯定会为字符串连接键,但你必须非常小心。

你将失去一个拥有这个新物体的空间,但是通过减少地图的数量可以节省相当多的空间,其中许多可能相对空白。

答案 2 :(得分:0)

因为这听起来像一个静态表 - 没有修改 - 创建类:

public class MyValues {
    String key;
    double value1;
    double value2;
}

创建对象并放置在数组MyValues[]中,然后按键排序。

编写二进制搜索算法以查找表中的值。 (这是一段非常简单的代码 - 大约20行。)

(对外层使用常规HashMaps。)

答案 3 :(得分:0)

我找到了一个解决方案,每个双数组使用大约22个字节,方法如下:

  • 使用double []代替Double []
  • 我按照第一层键获得的数据,我使用了Trove库中的THashMap。 HashMap的这个实现有一个紧凑的方法,它将HashMap的大小缩小到它现在拥有它所拥有的所有元素所需的大小。通过定期调用此功能,我能够不断调整大小。