Java对象的大小[重复]

Posted

技术标签:

【中文标题】Java对象的大小[重复]【英文标题】:sizeof Java object [duplicate] 【发布时间】: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);  

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

【问题讨论】:

为什么需要知道对象的大小? 如果你真的需要知道...***.com/questions/52353/… 考虑我们的内存有限并且应用程序有多个占用空间的对象的场景,然后我们将如何识别哪个对象占用更多空间并相应地进行处理。 有限的内存可能在任何地方,可能是我的台式机/笔记本电脑与我正在运行的应用程序相关 这能回答你的问题吗? In Java, what is the best way to determine the size of an object? 【参考方案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只是在上面给出了一个链接,看看,看起来不错!

以上是关于Java对象的大小[重复]的主要内容,如果未能解决你的问题,请参考以下文章

Java Script函数变量对象

怎么确定Java对象的大小

java list的重复对象怎么去除

java list的重复对象怎么去除

java如何获取一个对象的大小

java如何去掉list内的重复对象