1

可能重复:
在 Java 中,确定对象大小的最佳方法是什么?

我在网上找到了这段代码:

static Runtime runtime = Runtime.getRuntime();
...
long start, end;
Object obj;
runtime.gc();
start = runtime.freememory();
obj = new Object(); // Or whatever you want to look at
end =  runtime.freememory();
System.out.println("That took " + (start-end) + " 
bytes.");

但这不是很可靠,关于如何做得更好的任何想法?

4

2 回答 2

2

JVM 以块的形式分配内存,因此可以跨线程同时执行。这称为线程局部分配缓冲区

TLAB - 线程本地分配缓冲区。用于快速分配堆空间而无需同步。编译后的代码有一条由几条指令组成的“快速路径”,这些指令试图在当前线程的 TLAB 中碰撞高水位标记,如果碰撞标记落在 TLAB 特定的限制地址之前,则成功分配对象。

如果您将其关闭,-XX:-UseTLAB您将获得更准确的内存使用信息。

public static void main(String... args) {
    for (int i = 0; i < 10; i++) {
        long used1 = memoryUsed();
        new Object();
        long used2 = memoryUsed();
        System.out.println(used2 - used1);
    }
}

public static long memoryUsed() {
    return Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory();
}

使用默认选项打印

0 0 0 0 0 0 0 0 0 0

-XX:-UseTLAB

16 16 16 16 16 16 16 16 16 16

于 2012-12-01T12:41:10.953 回答
1

我有一些测量对象大小的经验,我学到的一件事是不信任分析器。它没有给出真实的测量值,而是猜测。具体来说,它在 64 位 VM 上误判了参考数组的大小 100%:实际大小是每个插槽 32 位,它猜测为 64 位。

只要您非常小心地熟悉您的特定配置并确保您获得一致的结果,您的测量方式实际上是可以的。一些额外的建议:

  1. 永远不要测量单个对象的大小,而是测量一千个或一百万个对象的数组。在对象之间共享数据的情况下(非常典型的场景),这对于提供更真实的结果非常重要。更改数组大小以查看每个对象的结果始终相同;

  2. 在分配数组之前和之后做两System.gc()到三秒,在它们之间暂停半秒左右;

  3. 不要仅仅freeMemory因为堆可以增长而测量;测量totalMemory() - freeMemory()

于 2012-12-01T12:42:18.317 回答