Java 如果不使用探查器,对象有多大

Java 如果不使用探查器,对象有多大,java,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("Th

可能重复:

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

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.");

但是它不是很可靠,你知道如何做得更好吗?

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();
}
publicstaticvoidmain(字符串…参数){
对于(int i=0;i<10;i++){
长时间使用1=已记忆();
新对象();
长时间使用2=记忆已使用();
System.out.println(used2-used1);
}
}
公共静态长内存(){
返回Runtime.getRuntime().totalMemory()-Runtime.getRuntime().freemory();
}
使用默认选项打印

0 0 0 0 0 0 0 0 0 0

使用
-XX:-UseTLAB

十六, 16 16 16 16 16 16 16 16
16

我在测量物体大小方面有一些经验,我学到的一件事是不要相信探查器。它不会给出实际的测量值,但会对进行估计。为了使这一点非常具体,它在64位虚拟机上100%地误判了引用数组的大小:在实际大小为每个插槽32位的情况下,它猜测的是64位

只要您非常小心地熟悉您的特定配置,并确保获得一致的结果,您的测量方法实际上是很好的。还有一些建议:

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

  • 在分配数组之前和之后执行两到三次
    System.gc()
    s,在它们之间暂停半秒钟左右

  • 不要只测量
    freemory
    ,因为堆可能会增长;测量
    totalMemory()-freemory()


  • 您可以序列化对象并查看保存了多少数据。显然,这将不同于内存中的对象大小!“关于如何做得更好有什么想法吗?”有什么好的理由吗?请参阅以获得更可靠的方法。请在您的问题中解释您想用此代码做什么哇,这么多批评者…此代码仅用于了解VM内部发生的情况,而不是任何生产或项目代码的一部分。这确实更好,Thx.说到信任,
    System.gc()
    肯定是我不信任的:)@MiljenMikic你是根据这种微基准的实际经验说的吗?我从未遇到过任何来自
    System.gc()
    I的不确定性,它在不同的实现中有所不同,但在一个固定的环境中是完全稳定和可预测的。不是使用这种基准测试,而是通常在其他应用程序中。我曾在两个项目中尝试依赖
    System.gc()
    ,但在跟踪内存消耗后放弃了,因为它确实有“自己的想法”。这是Sun JDK Java 1.6.0xx的实现。是的,
    System.gc()
    不是解决实时生产应用程序内存问题的工具。