Java 中空类的大小

10 Sept 2024 | 4 分钟阅读

在 Java 中,对象的大小是通过其实例变量大小的总和来确定的。然而,对于一个空类,即没有实例变量的类,关于它占用多少内存并没有一个明确的答案。这是因为 JVM(Java 虚拟机)有一个最小对象大小,通常是 8 字节,这是 Java 中可以分配的最小可能对象的大小。为了理解 Java 中空类的大小这一概念,让我们先讨论一下 Java 中的内存分配过程。当在 Java 中创建一个对象时,JVM 会在堆中分配内存来存储对象的实例变量。分配的内存大小取决于对象中实例变量的类型和数量。

然而,JVM 有一个最小对象大小,通常是 8 字节,这是 Java 中可以分配的最小可能对象的大小。这意味着即使对象没有实例变量,它仍然会占用 8 字节的内存。

让我们通过一个示例程序来更好地理解这个概念

这是一个没有任何实例变量的空类。让我们使用以下代码来确定这个类在 Java 中的大小

Size.java

输出

Size of EmptyClass object: 16

在上面的代码中,我们首先创建了一个 EmptyClass 的实例,然后使用 Runtime 类来计算 JVM 占用的内存。totalMemory() 方法返回 JVM 为应用程序分配的总内存量,freeMemory() 方法返回 JVM 中的可用内存量。通过将总内存减去可用内存,我们可以得到 EmptyClass 对象占用的内存量。如前所述,Java 中最小的对象大小通常是 8 字节。然而,在本例中,EmptyClass 对象的大小是 16 字节。这是因为 JVM 会为它分配的每个对象添加一些额外的元数据。对于空类,这些元数据包括一个指向类元数据的引用和一个指向类的方法元数据的引用。因此,即使 EmptyClass 没有实例变量,它仍然占用 16 字节的内存。需要注意的是,对象在 Java 中的实际大小可能会因 JVM 的实现、操作系统和硬件的不同而有所不同。

让我们来看另一个示例,以了解对象的大小如何根据其包含的实例变量而变化

在本例中,我们有一个名为 MyClass 的类,它有三个 int、char 和 boolean 类型的实例变量。让我们使用以下程序来确定这个类在 Java 中的大小

SizeOfClass.java

输出

Size of MyClass object: 16

从输出中可以看出,MyClass 对象的大小也是 16 字节。这是因为每个 int 变量占用 4 字节,char 变量占用 2 字节,boolean 变量占用 1 字节。因此,实例变量的总大小是 7 字节,但 JVM 向对象添加了 9 字节的元数据,导致总大小为 16 字节。需要注意的是,对象在 Java 中的大小也可能受到填充的影响。填充是添加额外字节到对象以确保其实例变量对齐到内存边界的技术。这可以通过使 CPU 更容易、更快地读写内存来提高性能。

例如,假设我们有一个类,其中有两个 int 变量

在本例中,两个 int 变量总共占用 8 字节(每个 4 字节)。然而,JVM 可能会向对象添加额外的填充字节,以确保 int 变量对齐到内存边界(通常是 4 字节)。这可能导致对象占用超过 8 字节的内存。

总之,Java 中空类的大小不是零,而是通常为 8 字节(Java 中的最小对象长度)。这是因为 JVM 会为它分配的每个对象添加一些额外的元数据,例如指向类元数据的引用和指向类的方法元数据的引用。Java 中对象的大小也可能受其包含的实例变量和填充的影响。需要注意的是,对象在 Java 中的实际大小可能会因 JVM 的实现、操作系统和硬件的不同而有所不同。