什么决定了Java对象的大小? [英] What determines Java object size?

查看:100
本文介绍了什么决定了Java对象的大小?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

对内存中单个对象的大小有什么贡献?

What contributes to the size of a single object in memory?

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

I know that primitives and references would, but is there anything else? Would the number of methods and the length of them matter?

推荐答案

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

This is completely implementation-dependent, but there are a few factors that influence object size in Java.

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

First, the number and types of the fields in the Java object definitely influence space usage, since you need to have at least as much storage space as is necessary to hold all of the object's fields. However, due to padding, alignment, and pointer compression optimizations, there is no direct formula you can use to compute precisely how much space is being used this way.

至于方法,通常说对象中的方法数量对其大小没有影响。方法通常使用名为虚拟功能表(或vtable)的功能实现,在常量时间内通过基类引用调用方法。这些表通常是通过在多个对象之间共享vtable的单个实例来存储的,然后让每个对象存储一个指向vtable的单个指针。

As for methods, typically speaking the number of methods in an object has no impact on its size. Methods are often implemented using a feature called virtual function tables (or "vtables") that make it possible to invoke methods through a base class reference in constant time. These tables are usually stored by having a single instance of the vtable shared across multiple objects, then having each object store a single pointer to the vtable.

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

Interface methods complicate this picture a bit, because there are several different implementations possible. One implementation adds a new vtable pointer for each interface, so the number of interfaces implemented may affect object size, while others do not. Again, it's implementation dependent how things are actually put together in memory, so you can't know for certain whether or not this will have a memory cost.

最好据我所知,目前没有JVM的实现,其中方法的长度会影响对象的大小。通常,每个方法只有一个副本存储在内存中,然后在特定对象的所有实例之间共享代码。使用更长的方法可能需要更多内存,但不应影响类实例的每对象内存。也就是说,JVM规范没有做出必须如此的承诺,但我想不出一个合理的实现会为方法代码花费额外的每个对象空间。

To the best of my knowledge there are no implementations of the JVM in existence today in which the length of a method influences the size of an object. Typically, only one copy of each method is stored in memory, and the code is then shared across all instances of a particular object. Having longer methods might require more total memory, but should not impact the per-object memory for instances of a class. That said, the JVM spec makes no promises that this must be the case, but I can't think of a reasonable implementation that would expend extra space per object for method code.

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

In addition to fields and methods, many other factors could contribute to the size of an object. Here's a few:

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

Depending on what type of garbage collector (or collectors) that the JVM is using, each object might have extra storage space to hold information about whether the object is live, dead, reachable, etc. This can increase storage space, but it's out of your control. In some cases, the JVM might optimize object sizes by trying to store the object on the stack instead of the heap. In this case, the overhead may not even be present for some types of objects.

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

If you use synchronization, the object might have extra space allocated for it so that it can be synchronized on. Some implementations of the JVM don't create a monitor for an object until it's necessary, so you may end up having smaller objects if you don't use synchronization, but you cannot guarantee that this will be the case.

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

Additionally, to support operators like instanceof and typecasting, each object may have some space reserved to hold type information. Typically, this is bundled with the object's vtable, but there's no guarantee that this will be true.

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

If you use assertions, some JVM implementations will create a field in your class that contains whether or not assertions are enabled. This is then used to disable or enable assertions at runtime. Again, this is implementation-specific, but it's good to keep in mind.

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

If your class is a nonstatic inner class, it may need to hold a reference to the class that contains it so that it can access its fields. However, the JVM might optimize this away if you never end up using this.

如果使用匿名内部类,则类可能需要保留额外的空间来保存 final 变量在其封闭范围内可见,以便可以在类中引用它们。它是特定于实现的,无论这些信息是复制到类字段还是仅存储在堆栈本地,但它可以增加对象大小。

If you use an anonymous inner class, the class may need to have extra space reserved to hold the final variables that are visible in its enclosing scope so that they can be referenced inside the class. It's implementation-specific whether this information is copied over into the class fields or just stored locally on the stack, but it can increase object size.

<$ c的一些实现$ c> Object.hashCode()或 System.identityHashCode(Object)可能需要在每个包含值的对象中存储额外信息哈希代码,如果它不能以任何其他方式计算它(例如,如果对象可以在内存中重新定位)。这可能会增加每个对象的大小。

Some implementations of Object.hashCode() or System.identityHashCode(Object) may require extra information to be stored in each object that contains the value of that hash code if it can't compute it any other way (for example, if the object can be relocated in memory). This might increase the size of each object.

这篇关于什么决定了Java对象的大小?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆