【问题标题】:Calculating memory usage of a B-Tree in Java在 Java 中计算 B-Tree 的内存使用量
【发布时间】:2013-03-31 15:25:40
【问题描述】:

我已经实现了一个简单的B-Tree,它将长映射到整数。现在我想使用以下方法(仅适用于 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 是否能够以某种方式优化内存布局,例如。对于空数组或我的错误是什么?

Update1:​​好的,引入 isLeaf 布尔值可以大大减少内存使用量,但仍不清楚为什么我观察到的值高于 Xmx。 (您仍然可以通过对所有构造函数使用 isLeaf == false 来尝试此操作)

Update2:嗯,有点不对劲。当增加每个叶子的条目时,会假设内存使用量减少(当对两者都进行压缩时),因为较大的数组涉及较少的引用开销(并且 btree 具有较小的高度)。但是,如果我使用 500 而不是每片叶子 100 个条目,则 memoryUsage 方法会报告增加的值。

【问题讨论】:

  • 长容量3*12的出处是什么?
  • long和int的内存消耗值你的来源是什么。
  • @Erik 3*12 -> 对 3 个数组的引用。
  • @PeterMmm 你是什么意思?

标签: java memory-management jvm b-tree


【解决方案1】:

哦,嘘……新鲜空气解决了这个问题;)

当一个条目已满时,它将被拆分。在我最初的拆分方法checkSplitEntry(我想避免浪费内存)中,我犯了一个很大的内存浪费错误:

// left child: just copy pointer and decrease size to index
BTreeEntry newLeftChild = this;
newLeftChild.entrySize = splitIndex;

这里的问题是,旧的子指针仍然可以访问。因此,在我的 memoryUsage 方法中,我数了一些孩子两次(尤其是当我没有压缩时!)。所以,如果没有这个技巧,一切都会好起来的,而且我的 B-Tree 的内存效率会更高,因为垃圾收集器可以完成它的工作!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-11-05
    • 2011-09-03
    • 2012-04-04
    • 2016-10-21
    • 2011-02-27
    相关资源
    最近更新 更多