Java中对象的大小是多少?

5

众所周知,Java使用以下数据类型:

byte    Occupy 8 bits in memory
short   Occupy 16 bits in memory
int     Occupy 32 bits in memory
long    Occupy 64 bits in memory 

如果我创建一个类似以下的类:
class Demo{
    byte b;        
    int i;
    long l;
}

Demo obj = new Demo();

现在我的问题是,obj的大小是< 、> 或 =b+i+l的大小,而b+i+l的大小为104字节。请给我适当的解释和理由。
谢谢, Anil Kumar C

请查看http://docs.oracle.com/javase/6/docs/api/java/lang/instrument/Instrumentation.html,它将帮助您大致测量对象的大小。 - yatul
仪器化如何帮助? - Thomas Uhrig
2
请参考 https://dev59.com/TnVD5IYBdhLWcg3wNIzc 了解如何计算对象在内存中的大小。 - Teg
1
你可以看一下这个链接:几乎相同的问题 - Konstantin V. Salikhov
它包含一个名为getObjectSize的方法,用于估计对象大小。以下是用法示例:http://www.javamex.com/tutorials/memory/instrumentation.shtml - yatul
5个回答

8

http://www.javamex.com/tutorials/memory/object_memory_usage.shtml

  1. 一个普通的对象占用8个字节;
  2. 一个只有一个布尔字段的类的实例占用16个字节:8个字节的头部,1个字节的布尔值和7个字节的“填充”,使其大小成为8的倍数;
  3. 具有8个布尔字段的实例也将占用16个字节:8个用于头部,8个用于布尔字段;由于这已经是8的倍数,因此不需要填充;
  4. 具有两个长整型字段、三个整型字段和一个布尔值的对象将占用:
    • 8个字节用于头部;
    • 16个字节用于2个长整型字段(每个字段8个字节);
    • 12个字节用于3个整型字段(每个字段4个字节);
    • 1个字节用于布尔值;
    • 另外3个字节的填充,将总大小从37调整为40,成为8的倍数。

这是比已被接受的更准确的答案。 - Ashish Bhosle

4
对象的内存大小取决于架构,主要取决于VM是32位还是64位。实际的VM实现也很重要。
对于每个对象,您需要为其对象头(在64位VM上通常为2 * 8字节)和其字段(根据VM实现的对齐而需要额外的空间)提供空间。最终的空间将四舍五入到字大小的最近倍数。

今天的愚蠢问题是:方法引用怎么样?它们在对象中吗?如果是这样,对于每个方法,我们应该添加其引用的大小。 - BigMike
2
@BigMike:通常,方法引用是类对象的一部分,而不是实例化对象的一部分。当然,基于HotSpot的虚拟机可以自行决定是否增加复杂性... - thkala
所以基本上至少要有一个对虚拟表的引用(我可以使用这个术语吗?)必须总结为对象大小,或者虚拟机是否完全保持对象实例和类分开?- 我在句子中不正确地使用了类。 - BigMike
@BigMike:如果我没记错的话,每个对象的头部都包含对应类对象的引用。方法引用并不会为每个新实例复制一次... - thkala
在32位和64位JVM中,对象分配是8字节对齐的。 - Peter Lawrey

2

很难确定对象在内存中的大小,类型大小指示有助于开发人员,但实际上在内存中它有些不同。我建议您阅读这篇文章,它非常有趣。


1

首先,你混淆了位和字节。

其次,它还需要指向“vtable”的指针,其中存储了有关其类的信息。在32位系统上,它很可能是4个字节(32位),而在64位系统上则为8个字节。

最后,请注意由于内存碎片化,总程序内存可能高于所有对象的总和。


+1 我只是想知道方法引用如何发挥作用。 - BigMike

0

在32位JVM上,对象头可以占用8个字节,在64位JVM上可以占用12个字节。

每个原始类型所占的位数不同(而非你所指的字节数)。

对象分配是按8字节对齐的,因此对象末尾可能会有最多7个字节的填充。也就是说,实际使用的空间会向上舍入到下一个8的倍数。

class Demo{ // 8 or 12 bytes
    byte b; // 1 byte
    int i;  // 4 bytes
    long l; // 8 bytes
}

Demo obj = new Demo();

因此,在32位JVM上,对象的大小可以占用24个字节,在64位JVM上则可以占用32个字节。


1
对象的头在32位JVM上可以占用8个字节,在64位JVM上可以占用12个字节。那么它们之间有什么区别呢? - MaVRoSCy

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接