大小固定的Hashtable 如果尚不熟悉Hashtable 和Hashmap,你可能想知道到底什么是大小固定的Hashtable (特别是,这些类的Java 实现大小都是不固定的)。 从概念上讲,一个Hashtable 包含一个数组,它会保存一些条目(数组中的每个元素叫 作一个桶)。当要将一个对象保存到Hashtable 中时,可以用该对象的哈希值对桶的数 目取余,以此确定对象在数组中的存储位置。这种情况下,两个哈希值不同的对象很 有可能被映射到同一个桶中,每个桶实际就是一个链表,其中按顺序存储了映射到该 桶的条目。当两个对象映射到一个桶时,这就叫“冲突”。 随着越来越多的对象被插入到这个表中,冲突也会越来越多;进而会有更多的条目被 插入到每个链表中。要找到一个条目,就变成了在一个链表中搜索。这可能会非常慢, 特别是随着链表越来越长,速度会更慢。 解决方案是设置Hashtable 的大小,以便它有更多的桶(当然,结果就是冲突会减少)。 很多实现都是动态处理的;实际上,Java 的Hashtable 和HashMap 也是这么工作的。 其他实现,像这里讨论的JVM 内部的这个,就不能重新设置Hashtable 的大小;其数 组的大小是在创建时就固定的。
从Java 7 中开始,这个表的大小可以在JVM 启动时使用-XX:StringTableSize=N(如前面
所介绍的,默认值为1009 或60 013) 。如果某个应用会保留大量字符串,就应该增加这个
值。如果这个值是个素数,字符串保留表的效率最高。
如果将字符串表设得特别大,其损失是非常小的:每个桶只需要4 字节或8 字节(取决于
使用的是32 位还是64 位JVM),所以比最优的情况多几千,只是一次性消耗一些原生内
存(不是堆内存)。