可能重复:
In Java, what is the best way to determine the size of an object?
我在网上找到了这段代码:
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.");
但它不是很可靠,对于如何做得更好有任何想法?
答案 0 :(得分:2)
JVM以块的形式分配内存,因此可以同时跨线程执行。这称为Thread-Local Allocation Buffer。
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
答案 1 :(得分:1)
我有一些测量对象大小的经验,我学到的一件事是不信任探查器。它没有给出真实的测量值,但 guestimates 。为了使其非常具体,它在64位VM上误判了参考阵列的大小100%:其中实际大小为每插槽32位,它猜测为64位。
只要您非常小心地熟悉特定配置并确保获得一致的结果,您的测量方法实际上就可以了。一些额外的建议:
永远不会测量单个对象的大小,而是测量一千个或一百万个对象的数组。这对于在对象之间的数据共享的情况下给出更真实的结果是很重要的(这是一种非常典型的场景)。更改数组大小以查看每个对象的结果始终相同;
在分配数组之前和之后做两到三个System.gc()
,在它们之间暂停半秒左右;
不要只测量freeMemory
,因为堆可以增长;衡量totalMemory() - freeMemory()
。