一个拥有100个属性的对象所消耗的内存空间是否与100个对象各有一个属性所消耗的内存空间相同?
为一个对象分配了多少内存? 添加属性时使用了多少额外空间?
一个拥有100个属性的对象所消耗的内存空间是否与100个对象各有一个属性所消耗的内存空间相同?
为一个对象分配了多少内存? 添加属性时使用了多少额外空间?
当前回答
我已经从另一个答案中提到的java.lang.instrument.Instrumentation方法中获得了非常好的结果。有关它的使用示例,请参阅java专家通讯和java。SourceForge上的sizeOf库。
其他回答
不,注册一个对象也会占用一些内存。100个具有1个属性的对象将占用更多内存。
我已经从另一个答案中提到的java.lang.instrument.Instrumentation方法中获得了非常好的结果。有关它的使用示例,请参阅java专家通讯和java。SourceForge上的sizeOf库。
一个拥有100个属性的对象所消耗的内存空间是否与100个对象各有一个属性所消耗的内存空间相同?
No.
为一个对象分配了多少内存?
32位的开销是8字节,64位的是12字节;然后四舍五入为4字节(32位)或8字节(64位)的倍数。
添加属性时使用了多少额外空间?
属性范围从1字节(byte)到8字节(long/double),但引用是4字节还是8字节,这并不取决于它是32位还是64位,而是取决于-Xmx是否< 32Gb或>= 32Gb:典型的64位JVM有一个名为“-UseCompressedOops”的优化,如果堆低于32Gb,它会将引用压缩到4字节。
在32位系统上,每个对象的开销似乎是16字节(在64位系统上是24字节)。
http://algs4.cs.princeton.edu/14analysis/是一个很好的信息来源。下面是一个很好的例子。
http://www.cs.virginia.edu/kim/publicity/pldi09tutorials/memory-efficient-java-tutorial.pdf的信息也非常丰富,例如:
这取决于架构/jdk。对于现代JDK和64位体系结构,一个对象有12字节的头部和8字节的填充-因此最小对象大小是16字节。您可以使用一个名为Java对象布局的工具来确定大小,并获得关于任何实体的对象布局和内部结构的详细信息,或者通过类引用来猜测这些信息。在我的环境中输出Integer的例子:
Running 64-bit HotSpot VM.
Using compressed oop with 3-bit shift.
Using compressed klass with 3-bit shift.
Objects are 8 bytes aligned.
Field sizes by type: 4, 1, 1, 2, 2, 4, 4, 8, 8 [bytes]
Array element sizes: 4, 1, 1, 2, 2, 4, 4, 8, 8 [bytes]
java.lang.Integer object internals:
OFFSET SIZE TYPE DESCRIPTION VALUE
0 12 (object header) N/A
12 4 int Integer.value N/A
Instance size: 16 bytes (estimated, the sample instance is not available)
Space losses: 0 bytes internal + 0 bytes external = 0 bytes total
因此,对于Integer,实例大小为16字节,因为4字节int压缩在头文件之后和填充边界之前。
代码示例:
import org.openjdk.jol.info.ClassLayout;
import org.openjdk.jol.util.VMSupport;
public static void main(String[] args) {
System.out.println(VMSupport.vmDetails());
System.out.println(ClassLayout.parseClass(Integer.class).toPrintable());
}
如果你使用maven,得到JOL:
<dependency>
<groupId>org.openjdk.jol</groupId>
<artifactId>jol-core</artifactId>
<version>0.3.2</version>
</dependency>