我已经实现了一个简单的B-树,它将长整型映射为整数。现在,我想使用以下方法(仅适用于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));
}
但是我尝试了700万条记录,而"memoryUsage"方法报告的值比-Xmx设置允许的值要高得多!例如,它显示1040(MB),而我设置了-Xmx300!JVM是否能够优化内存布局,例如对于空数组或我的错误是什么?
更新1:好的,引入isLeaf布尔值可以大大减少内存使用量,但仍然不清楚为什么观察到的值比Xmx高。(您仍然可以通过将isLeaf == false用于所有构造函数来尝试此方法)
更新2:嗯,有些事情出了问题。当增加每个叶子的条目数时,人们会认为内存使用量会减少(当对两者进行紧凑处理时),因为较大的数组涉及更少的引用开销(并且btree的高度更小)。但是,如果我使用500而不是每个叶子100个条目,则"memoryUsage"方法报告了一个增加的值。