我已经实现了一个简单的B-Tree,它将 long 映射到 int。现在我想使用以下方法估计它的内存使用情况(仅适用于 32 位 JVM):
class BTreeEntry {
int entrySize;
long keys[];
int values[];
BTreeEntry children[];
boolean isLeaf;
...
/** @return used bytes */
long capacity() {
long cap = keys.length * (8 + 4) + 3 * 12 + 4 + 1;
if (!isLeaf) {
cap += children.length * 4;
for (int i = 0; i < children.length; i++) {
if (children[i] != null)
cap += children[i].capacity();
}
}
return cap;
}
}
/** @return memory usage in MB */
public int memoryUsage() {
return Math.round(rootEntry.capacity() / (1 << 20));
}
但是我尝试了例如 7mio 条目,并且 memoryUsage 方法报告的值比 -Xmx 设置允许的值高得多!例如,它说 1040 (MB),我设置了 -Xmx300!JVM 是否能够以某种方式优化内存布局,例如。对于空数组或我的错误可能是什么?
更新 1:好的,引入 isLeaf 布尔值大大减少了内存使用量,但仍不清楚为什么我观察到的值高于 Xmx。(您仍然可以通过对所有构造函数使用 isLeaf == false 来尝试此操作)
更新2:嗯,有些事情很不对劲。当增加每个叶子的条目时,会假设内存使用量减少(当对两者都进行压缩时),因为较大的数组涉及较少的引用开销(并且 btree 具有较小的高度)。但是如果我使用 500 而不是每片叶子 100 个条目,则 memoryUsage 方法会报告增加的值。