假设我在一个哈希图中存储了1000个对象。扩展了此哈希图,使我可以将三维坐标映射到其中存储的对象。内部的对象具有固定的大小。哈希键是一个长整数。
我将如何计算(数学上)此结构的可能开销?
我对哈希表的总大小不感兴趣-仅会产生使用哈希表的开销。例如,如果我有10个整数,则它们是4个字节,所以是40个字节。如果将它们粘贴在数组中,则会得到12字节的恒定开销-对象头为8,长度为4。如果将它们放在另一个结构(例如TreeSet)中,由于树需要节点,我的开销将不是恒定的-因此我可能会得到以n表示的开销,其中n是集合中的项目数。
对我来说,有些事情是显而易见的,这里我将作为起点。
这给了我一个多项式方程:36 + 24n
因此,我猜测使用长键的1000个数据对象的开销为24036字节。这有点微不足道的开销,但我的问题是,坐在那里的实际开销是多少?
第二个有效的问题是,不同的JVM有多少不同?有没有JVM独立的方法来解决?为了说明我的意思,请考虑仅具有32位对象标头的JVM-在查看数组时,您可能会说,即使大小因JVM而异,但可以合理估计数组的开销将变为8字节而不是在这种情况下为12。
我假设在相同版本的Java中实现了HashMap的固定实现。
我可以尝试阅读源代码或运行概要分析,但是这可能会基于我的JVM产生误导性的结果。我正在寻求您的帮助-也许是一个知道的人-获取一些我们俩都不了解情况的信息。谢谢!
参见下面的答案,实际估算可以表示为:
每个条目8个字,每个长8个字节,再加上8个字节的hashmap对象标头。
在我目前的环境(32位操作系统)中,使1个字= 4个字节。
因此,似乎不足100 KB。
最佳答案
以下blog post提供了有关该主题的一些松散数学。
此google code site提供了如何完成这些操作的说明。
在链接腐烂的情况下引用链接:
This is the cheat-sheet I compiled.
To compute the cost of a single (key, value) entry:
If you use HashMap or ConcurrentHashMap, the cost is 8 words (32 bytes)
So, consider this example from the javadoc:
LoadingCache graphs = CacheBuilder.newBuilder()
.maximumSize(10000)
.expireAfterWrite(10, TimeUnit.MINUTES)
.removalListener(MY_LISTENER)
.build(
new CacheLoader() {
public Graph load(Key key) throws AnyException {
return createExpensiveGraph(key);
}
});
The cost of an Entry in this structure this is computed as follows:
It's a Cache: +12 words
It uses maximumSize(): +4 words
It uses expiration: +4 words
Thus, each (key, value) entry would have a footprint of 20 words (thus 80 bytes in a 32bit VM, or 160 in a 64bit one).
To estimate the overhead imposed in the garbage collector, one could count how many references (pointers) each entry introduces, which the garbage collector would have to traverse to compute object reachability. The same list again, this time only counting references:
If you use HashMap or ConcurrentHashMap, the cost is 5 references
关于java - 用Java计算HashMap开销,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/11565554/