【问题标题】:sizeof Java object [duplicate]Java对象的大小[重复]
【发布时间】:2011-05-06 03:22:07
【问题描述】:

我们如何知道 Java 对象的大小?

例子:

class Person{
    String name;  
    int age;  

    public Person(String n, int a){  
        name = n;  
        age = a;  
    }
}  

Person person = new Person("Andy", 30);  

如何知道人物对象的大小?

【问题讨论】:

标签: java sizeof


【解决方案1】:

这个问题没有意义,至少没有进一步的上下文。

Java 中“大小”的概念仅针对原语进行了合理的定义:一个字节是 8 位(不出所料)int 是 32 位,long 是 64 位等(参见例如 http://download.oracle.com/javase/tutorial/java/nutsandbolts/datatypes.html完整列表)。

对于对象实例,它更复杂,因为:

  • 对象实例可以(并且通常会)在内部包含对其他实例的引用,因此您必须决定是否计算这些依赖实例以及如何计算。如果多个实例共享一个依赖项怎么办?
  • 有时,对象实例可能会被重用(例如 java.lang.String 的实习,请参阅 http://en.wikipedia.org/wiki/String_interning )。所以如果你使用 x 大小为 y 的对象,总大小可能小于 x*y
  • JVM 对于如何在内部实现对象和实例有很大的余地。 它可能对不同的实例使用不同的技术(例如共享内部数据结构),因此甚至可能没有有意义的“大小”来分配给单个对象。

也许您可以解释一下为什么您对对象大小感兴趣。

估计实例使用的堆内存有一些经验法则(例如,在 Sun JVM 中,java.lang.Object 实例使用 8 字节),但这些取决于您使用的 JVM。

通常,如果您想了解堆使用情况,请使用内存/堆分析器。

编辑:

嗯,(从 JDK 6 开始)有一种方法可以获取对象使用的内存量的近似值:http://download.oracle.com/javase/6/docs/api/java/lang/instrument/Instrumentation.html#getObjectSize%28java.lang.Object%29

这仍然只是一个近似值...

【讨论】:

    【解决方案2】:

    如果你这样做,我认为你可以获得一些可能对你有帮助的东西:

        /* First trigger classloading */
        MyObject delegate = new MyObject();
    
        Runtime.getRuntime().gc();
    
        long before = Runtime.getRuntime().freeMemory();
        MyObject delegate2 = new MyObject();
        long after = Runtime.getRuntime().freeMemory();
    
        System.out.println("Memory used:"+(before-after));
    

    这有望给你你想要的答案,或者至少是一个近似值。

    【讨论】:

    • 多线程的情况呢?如果同时分配两个大小相同的对象,则所用内存的值将是所需大小的两倍。
    • 我会为我想弄乱的对象做一个小的受控测试。如果您在线程环境中执行此操作,那么所有的赌注都没有了。
    【解决方案3】:

    EhCache 提供了一个SizeOf 类,该类将尝试使用Instrumentation 代理,如果代理未加载或无法加载(details here),它将回退到不同的方法。

    另见the agent from Heinz Kabutz

    【讨论】:

      【解决方案4】:

      您可以使用sizeof4j 库来计算java 中任何对象的大小,例如SizeOf.shallowSize(new Integer(2))

      【讨论】:

        【解决方案5】:

        对象。为了确定对象的内存使用情况,我们添加数量 每个实例变量使用的内存与相关的开销 每个对象,通常为 16 个字节。开销包括 引用对象的类、垃圾收集信息和 同步信息。此外,内存使用量通常是 填充为 8 字节的倍数(机器字,在 64 位 机器)。例如,一个 Integer 对象使用 24 个字节(16 个字节 开销,4 个字节的 int 实例变量,以及 4 个字节的 填充)

        参考:http://www.amazon.com/Algorithms-4th-Edition-Robert-Sedgewick/dp/032157351X

        【讨论】:

          【解决方案6】:

          Java 没有内置 sizeof 运算符。

          您可以尝试使用序列化方法,将对象序列化到内存并获取该数据的大小,但这不一定是您想要的大小。

          您还可以有一个名为sizeOf() 的方法,如下所示:

          // returns the size of this object in bytes
          int sizeOf()
          {
               int size = 0;
               size += name.Length * 2; // each character in name is 2 bytes, no?
               size += 4; // for n, which is 32 bits = 4 bytes
          }
          

          请注意,此实现不包含名称中的元数据,仅包含为其生成 char[] 所需的字节数。

          【讨论】:

          • 但这也不会显示标题需要多少空间。
          • 已编辑,我添加了该信息...老实说,我不认为 Java 曾经打算拥有这样的功能...
          • 我认为序列化不是精确的方法,因为它会在对象中添加元数据,以便反序列化过程知道如何重建对象
          • 正确。第二种方法更准确,但是,为什么你需要知道对象的大小.. 这个大小是否类似于 C/C++ sizeof
          • @Richard,我不知道,RD只是在上面给出了一个链接,看看,看起来不错!
          猜你喜欢
          • 2011-04-28
          • 2012-03-11
          • 2012-03-08
          • 1970-01-01
          • 1970-01-01
          • 2011-11-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多