I had a whim recently and suddenly became interested in the memory size of Java objects. I went to collect some information on the Internet and sorted it out. I hope you can help me. If: you can calculate the memory size occupied by the object new String ("abc") in the JVM (compressed size 48B, uncompressed size 64B in 64-bit JDK7), then you can end it here~
Memory layout of Java objects: Object header (Header), instance data (Instance Data) and alignment padding (Padding) ## #. The object header of the virtual machine includes two parts of information. The first part is used to store the runtime data of the object itself , such as hashCode, GC generation age, lock status flag, lock held by the thread, and bias Thread ID, bias timestamp, etc. The length of this part of data is 4B and 8B respectively in 32-bit and 64-bit virtual machines (pointer compression is not turned on). It is officially called "Mark Word". The other part of the object is the type pointer (klass) , which is the pointer of the object to its class metadata. The virtual machine uses this pointer to determine which class the object is an instance of. In addition, if the object is a Java array, there must be a piece of data in the object header to record the length of the array, because the virtual machine can determine the size of the Java object through the metadata information of ordinary Java objects, but from the metadata of the array But cannot determine the size of the array. The object header occupies 8B on 32-bit systems and 16B on 64-bit systems. Whether it is a 32-bit system or a 64-bit system, objects are 8-byte aligned. When Java turns on pointer compression in 64-bit mode, the header will be 4B larger than in 32-bit mode (the mark area is shifted by 8B, and the kclass area is compressed). If pointer compression is not turned on, the header will be 8B larger (both mark and kclass are compressed). is 8B) , in other words, HotSpot's alignment is 8-byte alignment: (object header + instance data + padding)%8 is equal to 0 and 0<=padding<8. The following instructions are based on HotSpot.
As mentioned in Reference 2, the java.lang.instrument.Instrumentation provided after JDK5 provides a rich API for tracking various aspects of structure and measuring object size. However, this thing requires the use of java agent. As for the agent and Instrumentation, I will not explain them here. I will only explain how to use them.
This class is provided in Reference Material 3. I personally think it is very practical. The code is shown in Appendix 1 below (the code is relatively long, so I will simply put it at the end of the article): This code can be copied directly, and then Pack it into a jar package (named agent.jar. If the packaging is not successful, you can directly download the package packaged by the blogger). Pay attention to adding a line in META-INF/MANIFEST.MF:
Give an example Case, the code is as follows (the blogger’s system is 64-bit and uses 64-bit JDK7):
import com.zzh.size.MySizeOf;public class ObjectSize
{ public static void main(String args[])
{
System.out.println(MySizeOf.sizeOf(new Object()));
}
}
Copy after login
Next, compile and run, the steps are as follows:
Compile (agent.jar is placed in the current directory): javac -classpath agent.jar ObjectSize.java
Run: java -javaagent:agent.jar ObjectSize (output result: 16, As for the analysis of this result, we will elaborate on it later)
JDK6 introduces the parameter -XX:+UseCompressedOops. This parameter will be automatically turned on by default in 32G memory. Pointer compression can be turned off by adding -XX:-UseCompressedOops to the run parameters.
Using Instrumentation to test the size of an object is just to express the size of an object more vividly. In fact, when an object is created, its size can be calculated manually. Code case practice is used to prove the rationality and correctness of theoretical knowledge. , the specific algorithm is reflected in the code case below.
Supplement: The memory usage of primitive type is as follows:
new Object()的大小=对象头12B(8Bmak区,4Bkclass区)+padding的4B=16B
Copy after login
案例2:
static class A{ int a;
} static class B{ int a; int b;
} public static void main(String args[])
{
System.out.println(MySizeOf.sizeOf(new Integer(1)));
System.out.println(MySizeOf.sizeOf(new A()));
System.out.println(MySizeOf.sizeOf(new B()));
}
Copy after login
输出结果:
(指针压缩) 16 16 24
(指针未压缩)24 24 24
Copy after login
分析1(指针压缩):
new Integer(1)的大小=12B对象头+4B的实例数据+0B的填充=16Bnew
A()的大小=12B对象头+4B的实例数据+0B的填充=16B
new B()的大小=12B对象头+2*4B的实例数据=20B,填充之后=24B
Copy after login
分析2(指针未压缩):
new Integer(1)的大小=16B对象头+4B的实例数据+4B的填充=24B
new A()的大小=16B对象头+4B的实例数据+4B的填充=24B
new B()的大小=16B对象头+2*4B的实例数据+0B的填充=24B
new int[2]的大小=12B对象头+压缩情况下数组比普通对象多4B来存放长度+2*4B的int实例大小=24B
new int[3]的大小=12B对象头+4B长度+3*4B的int实例大小=28B,填充4B =32B
new char[2]的大小=12B对象头+4B长度+2*2B的实例大小=20B,填充4B=24B
new char[3]的大小=12B对象头+4B长度+3*2B的实例大小+2B填充=24B
(PS:new char[5]的大小=32B)
Copy after login
分析2(指针未压缩):
new int[2]的大小=16B对象头+未压缩情况下数组比普通对象多8B来存放长度+2*4B实例大小=32B
new int[3]的大小=16B+8B+3*4B+4B填充=40B
new char[2]的大小=16B+8B+2*2B+4B填充=32B
new char[2]的大小=16B+8B+3*2B+2B填充=32B
(PS:new char[5]的大小为40B)
The above is the detailed content of A brief analysis of Java object size. For more information, please follow other related articles on the PHP Chinese website!
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn