gpt4 book ai didi

java - 什么决定了 Java 对象的大小?

转载 作者:IT老高 更新时间:2023-10-28 20:45:04 25 4
gpt4 key购买 nike

是什么影响了内存中单个对象的大小?

我知道原语和引用会,但还有别的吗?
方法的数量和长度重要吗?

最佳答案

这完全取决于实现,但有几个因素会影响 Java 中的对象大小。

首先,Java 对象中字段的数量和类型肯定会影响空间使用,因为您至少需要拥有容纳所有对象字段所需的存储空间。但是,由于填充、对齐和指针压缩优化,没有可用于精确计算这种方式使用的空间的直接公式。

至于方法,通常来说,对象中方法的数量对其大小没有影响。方法通常使用名为 virtual function tables 的特性实现。 (或“vtables”),可以在恒定时间内通过基类引用调用方法。这些表通常通过在多个对象之间共享 vtable 的单个实例来存储,然后让每个对象存储一个指向 vtable 的指针。

接口(interface)方法使这张图片有点复杂,因为可能有几种不同的实现。一种实现为每个接口(interface)添加了一个新的 vtable 指针,因此实现的接口(interface)数量可能会影响对象大小,而另一些则不会。同样,它的实现取决于事物在内存中的实际组合方式,因此您无法确定这是否会产生内存成本。

据我所知,目前还没有 JVM 的实现,其中方法的长度会影响对象的大小。通常,每个方法只有一个副本存储在内存中,然后代码在特定对象的所有实例之间共享。拥有更长的方法可能需要更多的总内存,但不应影响类实例的每个对象内存。也就是说,JVM 规范没有 promise 一定是这种情况,但我想不出一个合理的实现,它会为每个对象为方法代码消耗额外的空间。

除了字段和方法之外,许多其他因素也会影响对象的大小。这里有一些:

根据 JVM 使用的垃圾收集器(或多个收集器)类型,每个对象可能有额外的存储空间来保存有关对象是否存活、死亡、可访问等信息。这可以增加存储空间,但它已用完你的控制。在某些情况下,JVM 可能会通过尝试将对象存储在堆栈而不是堆上来优化对象大小。在这种情况下,某些类型的对象甚至可能不存在开销。

如果您使用同步,对象可能会分配额外的空间,以便它可以同步。 JVM 的某些实现在需要之前不会为对象创建监视器,因此如果不使用同步,最终可能会拥有较小的对象,但您不能保证会是这种情况。

此外,支持像 instanceof 这样的运营商和类型转换,每个对象可能会保留一些空间来保存类型信息。通常,这与对象的 vtable 捆绑在一起,但不能保证这是真的。

如果您使用断言,某些 JVM 实现将在您的类中创建一个字段,其中包含是否启用断言。这随后用于在运行时禁用或启用断言。同样,这是特定于实现的,但最好记住。

如果您的类是非静态内部类,则它可能需要保存对包含它的类的引用,以便它可以访问其字段。但是,如果您永远不会使用它,JVM 可能会优化它。

如果您使用匿名内部类,该类可能需要保留额外的空间来保存 final在其封闭范围内可见的变量,以便它们可以在类内被引用。是否将此信息复制到类字段中或仅存储在堆栈中是特定于实现的,但它会增加对象大小。
Object.hashCode() 的一些实现或 System.identityHashCode(Object)如果不能以任何其他方式计算它,则可能需要在每个包含该哈希码值的对象中存储额外信息(例如,如果该对象可以在内存中重新定位)。这可能会增加每个对象的大小。

关于java - 什么决定了 Java 对象的大小?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7060141/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com