Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/366.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java HashMap绝对容量_Java_Hashmap - Fatal编程技术网

Java HashMap绝对容量

Java HashMap绝对容量,java,hashmap,Java,Hashmap,我对代码中的一个HashMap对象进行了一些性能检查,发现在大约2000-2400个对象中添加对象会减慢速度。事实上,当它大约到达2400个对象时,它仍然被阻止,并且不允许更多的条目。这类对象是否有一个限制,即当它们被保存在内存中时,直到它们以某种方式被清空或回收后才允许更多的条目 非常感谢。运行此程序(在主课堂上): Map Map=newhashmap(); 用于(长l=0L;l

我对代码中的一个HashMap对象进行了一些性能检查,发现在大约2000-2400个对象中添加对象会减慢速度。事实上,当它大约到达2400个对象时,它仍然被阻止,并且不允许更多的条目。这类对象是否有一个限制,即当它们被保存在内存中时,直到它们以某种方式被清空或回收后才允许更多的条目

非常感谢。

运行此程序(在主课堂上):

Map Map=newhashmap();
用于(长l=0L;l<100000;l++){
map.put(Long.valueOf(l),String.valueOf(l));
}
System.out.println(map.size());
在我的机器上,它运行、输出和终止得如此之快,以至于我都没有注意到它


如果
hashCode()
算法良好,
HashMap
可以支持许多元素。显然,你的是坏的。

我能想到的唯一可以解释这个问题的东西是,如果你的对象非常大,你的堆快用完了。当这种情况发生时,JVM可以停止尝试清理的时间越来越长。在Java6中,它试图在它变得非常糟糕之前检测到这一点,并抛出OutOfMemoryError(在它完全耗尽内存之前,但未能清除很多内存),Java5.0没有这样做

这可以解释为什么当你丢弃一些物体时,事情会再次加速


HashMap的标准实现限制为大约7.5亿个条目(取决于您如何使用它,例如您的平均负载),它可以拥有的最大容量为2^30(十亿),并且在负载系数为0.75f(约7.5亿个条目)的情况下,它将尝试将基础阵列的大小增加一倍,这是它无法做到的。(因为最大大小是整数。最大值)

您可以使用LinkedHashMap作为缓存,根据必须提供的规则逐出“eldset”条目

但是,除非HashMap是同步的,否则它不会阻塞。如果它将失败,它将抛出一个异常

以这种方式获得阻止的映射的唯一一致方法是死锁

另一种可能发生这种情况的方式是,如果您在两个线程中以不安全的方式使用同一映射。在这种情况下,行为是未定义的,但是我看到它在JVM中导致问题(非常罕见),甚至“挂起”所涉及的线程。即使是这种情况,我也希望它在HashMap的增长中具有默认的加载因子,这将是3072(即4096*0.75),而不是您看到的值


即使有一个糟糕的hashCode实现也不能解释这个问题

static class BadHash {
    @Override
    public int hashCode() {
        return 1;
    }
}

public static void main(String... args) {
    Map<BadHash, Boolean> map = new HashMap<BadHash, Boolean>();
    for (int i = 0; i <= 100000; i++) {
        if (i % 10000 == 0) System.out.println(i + ": " + new Date());
        map.put(new BadHash(), true);
    }
}

显示您的代码plsHashMaps需要增长并在填充时重建。这需要一些时间,但不应该“保持阻塞”速度会很慢,但不会停止。它并不比使用LinkedList慢多少。和我上面写的评论一样。我必须说,我在Windows2003服务器的HashMap中添加了打开的BufferedWriter对象指针,但只要我知道该系统中打开的文件的限制远远大于2400个。可能无法在同一文件夹中获取这么多打开的文件。我必须说,我在Windows 2003服务器的HashMap中添加了打开的BufferedWriter对象指针,但只要我知道该系统中打开的文件的限制远远大于2400个。也许不能在同一个文件夹中打开这么多文件。@aztu,如果是这样的话,打开一个文件可能会失败或阻塞。您应该能够看到调用堆栈中的差异。必须是您所说的堆,因为操作系统中同时打开的文件的大小相当大。非常感谢你,你一直在说教。
static class BadHash {
    @Override
    public int hashCode() {
        return 1;
    }
}

public static void main(String... args) {
    Map<BadHash, Boolean> map = new HashMap<BadHash, Boolean>();
    for (int i = 0; i <= 100000; i++) {
        if (i % 10000 == 0) System.out.println(i + ": " + new Date());
        map.put(new BadHash(), true);
    }
}
0: Mon Sep 26 12:23:39 BST 2011
10000: Mon Sep 26 12:23:39 BST 2011
20000: Mon Sep 26 12:23:39 BST 2011
30000: Mon Sep 26 12:23:40 BST 2011
40000: Mon Sep 26 12:23:41 BST 2011
50000: Mon Sep 26 12:23:42 BST 2011
60000: Mon Sep 26 12:23:44 BST 2011
70000: Mon Sep 26 12:23:46 BST 2011
80000: Mon Sep 26 12:23:48 BST 2011
90000: Mon Sep 26 12:23:51 BST 2011
100000: Mon Sep 26 12:23:53 BST 2011