假设我在散列图中存储了1000个对象。这个hashmap被扩展为允许我将三维坐标映射到存储在其中的对象;里面的物体有固定的大小。散列键是一个长整数。
我如何计算(数学上)这种结构的可能开销?
我对hashmap的总大小不感兴趣 - 只有使用hashmap的开销才会产生。例如,如果我有10个整数,那么它就是4个字节,所以它是40个字节。如果我把它们粘在一个数组中,我得到一个12字节的常量开销 - 对象头为8,长度为4。如果我将它们放在另一个结构(例如TreeSet)中,我的开销将不会保持不变,因为树需要节点 - 因此我可能会得到以n表示的开销,其中n是集合中的项目数。
有些事情对我很明显,我将在此作为我的起点。
这给出了一个多项式方程:36 + 24n
因此,我猜测使用长密钥的1000个数据对象的开销为24036字节。这在某种程度上是一个微不足道的开销,但我的问题是,真正的开销是什么,只是坐在那里?
一个有效的第二个问题是,这从JVM到JVM有多大差异?是否有任何独立于JVM的方法来解决它?为了举例说明我的意思,考虑一个只有32位对象头的JVM - 在查看你可能会说的数组时,即使从JVM到JVM的大小不同,可以合理地估计一个数组上的开销会变成8个字节而不是在那种情况下12。
我假设在相同版本的Java上实现了HashMap的固定实现。
我可以尝试阅读源代码或运行分析,但这可能会产生基于我的JVM的误导性结果。我正在寻求你的帮助 - 或许有人知道 - 我们都不知道有关情况的一些信息。谢谢!
见下面的答案,实际估计可表示如下:
每个条目8个字,每个长度加8个字节,加上hashmap对象标题的8个字节。
在我目前的环境(32位操作系统)中,1个字= 4个字节。
所以它似乎低于100k字节。
答案 0 :(得分:1)
以下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
答案 1 :(得分:0)
创建一个程序,您可以在其中创建所有对象并将它们存储在一个简单的数组中。测量已用内存(请参阅Runtime)。
然后将它们存储在HashMap中。测量已用内存。
将第一个测量的内存减去第二个使用过的内存,你就有了HashMap的开销。
答案 2 :(得分:0)
- 是否足够重要,例如,如果内部数据大约为256mb,那么开销就很重要了?
醇>
绝对不是。在任何情况下,HashMap中1000个对象的开销甚至都不值得担心:如果它们总共为256mb,则更不用说。如果开销是256k,而不是,则只有1%。不重要。
- 是否有可靠的方法(除了我发现在某些情况下不可靠的分析器)以数学方式计算其开销应该是多少?
醇>
鉴于我对(1)的回答,这个问题没有实际意义。