ConcurrentHashMap内存开销

时间:2012-06-19 14:32:07

标签: java hashmap concurrenthashmap memory-profiling

有人知道ConcurrentHashMap的内存开销是什么(与“经典”HashMap相比)?

  • 在施工?
  • 插入元素?

3 个答案:

答案 0 :(得分:8)

如果在64位JVM上使用-XX:-UseTLAB -XX:NewSize=900m -mx1g运行以下内容。

public static void main(String... args) throws NoSuchMethodException, IllegalAccessException {
    for (int i = 0; i < 4; i++) {
        long used1 = usedMemory();
        populate(new HashMap());
        long used2 = usedMemory();
        populate(new ConcurrentHashMap());
        long used3 = usedMemory();
        System.out.println("The ratio of used memory is " + (double) (used3 - used2) / (used2 - used1));
        System.out.println("For an extra " + ((used3 - used2) - (used2 - used1)) / 1000000 + " bytes per entry was used.");
    }
}

private static void populate(Map map) {
    for (Integer i = 0; i < 1000000; i++)
        map.put(i, i);
}

private static long usedMemory() {
    return Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory();
}

你可以使用Java 6和7获得一百万个条目。

The ratio of used memory is 1.1291128466982379
For an extra 8 bytes per entry was used.
The ratio of used memory is 1.1292086928728067
For an extra 8 bytes per entry was used.
The ratio of used memory is 1.1292086928728067
For an extra 8 bytes per entry was used.
The ratio of used memory is 1.1292086928728067
For an extra 8 bytes per entry was used.

8 MB的内存成本约为5美分。

答案 1 :(得分:4)

ConcurrentHashMap在构造和插入时都没有使用比HashMap更多的内存。

初始化

ConcurrentHashMap使用与HashMap几乎相同的内存量,对于一些额外的簿记变量和锁可能稍微多一些。

在初始化期间,ConcurrentHashMap创建16个段来存储键值,每个段相当于一个HashMap。

每个细分的初始容量/大小是整个初始容量的1/16。所以实质上,ConcurrentHashMap创建了16个小HashMaps,相当于一个HashMap。每个Segment都有自己的锁和几个簿记变量(计数,阈值等),这是额外的内存开销。

您可以通过将适当的值传递给 concurrencyLevel 参数来ConcurrentHashMap来控制ConcurrentHashMap创建的细分数量。这个值越小,那么将使用更少的空间,但是当大量线程更新Map时会有更多争用。该值越高,则将创建更多段,但并行更新的性能将更快。注意: concurrencyLevel 参数的值显着更高,会影响空间和时间。

内存中的这种小开销是开发人员愿意接受以换取并发性的内容。

在插入

当细分填充时,该细分的大小将会增加。增加大小的策略与HashMap相同。 loadfactor 参数决定何时增加Segment的大小。请注意,填充的段将增加。内存开销再次与HashMap几乎相同。

总体而言,ConcurrentHashMap并未使用比HashMap更多的内存,但实际上很难衡量ConcurrentHashMap使用的每个额外字节。

答案 2 :(得分:2)

我真的不明白这个问题的前提 - 要么你需要并发,要么你不需要。

但是,根据this link,空ConcurrentHashMap的内存占用量为1700字节。如果您有多个需要读/写访问权限的线程,建议您使用ConcurrentHashMap,如果您有许多线程需要读取权限但是有一个需要写入,则建议使用Hashtable