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对象的大小[重复]的主要内容,如果未能解决你的问题,请参考以下文章