10

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

  • 在施工?
  • 在插入元素时?
4

3 回答 3

10

-XX:-UseTLAB -XX:NewSize=900m -mx1g如果您在 64 位 JVM 上运行以下命令。

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 美分。

于 2012-06-19T15:33:00.073 回答
4

ConcurrentHashMapHashMap在构造和插入时都不会使用比 更多的内存。

初始化时

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

初始化时,ConcurrentHashMap创建16个Segment来存储key-value,每个Segment相当于一个HashMap。

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

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

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

插入时

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

总体而言,ConcurrentHashMap它使用的内存并不比. 多得多HashMap,但很难测量ConcurrentHashMap.

于 2012-06-19T16:18:18.090 回答
2

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

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

于 2012-06-19T14:38:49.240 回答