How much memory a Java object occupies

Source: Internet
Author: User

Recently reading "In-depth understanding of Java Virtual Machine", the memory layout of Java objects have a further understanding, so naturally there is a very common problem, is a Java object how much memory?

Found on the Internet a blog is very good: http://yueyemaitian.iteye.com/blog/2033046, the inside of the class provided is also very useful:

?

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465 66676869707172737475767778798081828384858687888990919293949596979899 import java.lang.instrument.Instrumentation;  import java.lang.reflect.Array;  import java.lang.reflect.Field;  import java.lang.reflect.Modifier;  import java.util.ArrayDeque;  import java.util.Deque;  import java.util.HashSet;  import java.util.Set;    /**  * 对象占用字节大小工具类  *  * @author tianmai.fh  * @date 2014-03-18 11:29  */public class SizeOfObject {      static Instrumentation inst;         public static void premain(String args, Instrumentation instP) {          inst = instP;            /**      * 直接计算当前对象占用空间大小,包括当前类及超类的基本类型实例字段大小、<br></br>      * 引用类型实例字段引用大小、实例基本类型数组总占用空间、实例引用类型数组引用本身占用空间大小;<br></br>      * 但是不包括超类继承下来的和当前类声明的实例引用字段的对象本身的大小、实例引用数组引用的对象本身的大小 <br></br>      *      * @param obj      * @return      */    public static long sizeOf(Object obj) {          return inst.getObjectSize(obj);             /**      * 递归计算当前对象占用空间总大小,包括当前类和超类的实例字段大小以及实例字段引用对象大小      *      * @param objP      * @return      * @throws IllegalAccessException      */    public static long fullSizeOf(Object objP) throws IllegalAccessException {          Set<Object> visited = new HashSet<Object>();          Deque<Object> toBeQueue = new ArrayDeque<Object>();          toBeQueue.add(objP);          long size = 0L;          while (toBeQueue.size() > 0) {              Object obj = toBeQueue.poll();              //sizeOf的时候已经计基本类型和引用的长度,包括数组              size += skipObject(visited, obj) ? 0L : sizeOf(obj);              Class<?> tmpObjClass = obj.getClass();              if (tmpObjClass.isArray()) {                  //[I , [F 基本类型名字长度是2                  if (tmpObjClass.getName().length() > 2) {                      for (int i = 0, len = Array.getLength(obj); i < len; i++) {                          Object tmp = Array.get(obj, i);                          if (tmp != null) {                              //非基本类型需要深度遍历其对象                              toBeQueue.add(Array.get(obj, i));                                                                          } else                 while (tmpObjClass != null) {                      Field[] fields = tmpObjClass.getDeclaredFields();                      for (Field field : fields) {                          if (Modifier.isStatic(field.getModifiers())   //静态不计                                  || field.getType().isPrimitive()) {    //基本类型不重复计                              continue                                                  field.setAccessible(true);                          Object fieldValue = field.get(obj);                          if (fieldValue == null) {                              continue                                                toBeQueue.add(fieldValue);                                          tmpObjClass = tmpObjClass.getSuperclass();                                              return size;            /**      * String.intern的对象不计;计算过的不计,也避免死循环      *      * @param visited      * @param obj      * @return      */     static boolean skipObject(Set<Object> visited, Object obj) {          if (obj instanceof String && obj == ((String) obj).intern()) {              return true                return visited.contains(obj);      }

You can use this code to look at the side of the verification, note that the program needs to run through Javaagent injection instrumentation, the specific can see the original blog. Today I mainly summarize the basic rules of manually calculating the number of bytes used in Java objects, as basic skills must be get√, I hope to help the same Java novice.

Before the introduction, briefly review the memory layout of the Java object: the object header (header), the instance data (Instance), and the Align Fill (Padding), which can be seen in detail in my reading notes. In addition: Different environmental results may vary, my environment is hotspot virtual machine, 64-bit windwos.

Enter the following text:

Object Header

The object header occupies 16bytes on a 32-bit system that occupies the 8bytes,64 bit system.

instance Data

The memory consumption of the native type (primitive type) is as follows:

Primitive Type Memory Required (bytes)
Boolean 1
Byte 1
Short 2
Char 2
Int 4
Float 4
Long 8
Double 8

The reference type occupies 4bytes each on a 32-bit system and consumes 8bytes per 64-bit system.

Snap To fill

The alignment of the hotspot is 8-byte aligned:

(Object header + instance data + padding)% 8 equals 0 and 0 <= padding < 8

pointer Compression

The memory size that the object occupies receives the VM parameter usecompressedoops effect.

1) Impact on the object head

The open (-xx:+usecompressedoops) object header size is 12bytes (64-bit machine).

?

123 staticclass A {        inta;    }

A object takes up memory condition:

Turn off pointer compression: 16+4=20 is not a multiple of 8, so +padding/4=24

Turn on pointer compression: 12+4=16 is already a multiple of 8 and does not need to be padding.

2) Impact on reference type

The reference type occupies 8 bytes on a 64-bit machine and 4 bytes after the pointer compression is turned on.

?

1234 staticclass B2 {        intb2a;        Integer b2b;}

B2 Objects occupy Memory:

Turn off pointer compression: 16+4+8=28 is not a multiple of 8, so +padding/4=32

Turn on pointer compression: 12+4+4=20 is not a multiple of 8, so +padding/4=24

Array Object

On a 64-bit machine, the object header of an array object occupies 24 bytes, and 16 bytes is used after compression is enabled. More memory is consumed than ordinary objects because additional space is required to store the length of the array.

Consider the memory size of new integer[0], which is 0, which is the size of the object header:

Compression not turned on: 24bytes

After the compression is turned on: 16bytes

Then it is easy to calculate new Integer[1],new integer[2],new integer[3] and new integer[4]:

No compression is turned on:

To turn on compression:

Take new integer[3] to specifically explain:

Compression not turned on: 24 (object header) +8*3=48, no need to padding;

Turn on compression: 16 (object header) +3*4=28,+padding/4=32, others and so on.

The array of custom classes is the same, for example:

?

1234 staticclass B3 {        inta;        Integer b;    }

New B3[3] The amount of memory occupied:

Compression not turned on: 48

After turning on compression: 32

Compound Object

Calculating the size of a composite object's memory is actually a matter of using the above rules, just a bit of trouble.

1) Size of the object itself

Directly calculates the current object footprint, including the current class and superclass of the base type instance field size, Reference type instance field reference size, instance primitive type array total footprint, instance reference type array reference itself occupies the space size; But does not include the size of the object itself that inherits the superclass and the instance reference field of the current class declaration, and the size of the object itself referenced by the instance reference array.

?

1234567891011121314 static class B {        int a;        int b;    }static class C {        int ba;        B[] as = new B[3];        C() {            for (int i = 0; i < as.length; i++) {                as[i] = new B();            }        }    }

Compression not turned on: 16 (object header) +4 (BA) +8 (as referenced size) +padding/4=32

Open compression: 12+4+4+padding/4=24

2) Total amount of space occupied by the current object

Recursively calculates the total space occupied by the current object, including the instance field size of the current class and superclass, and the Instance field reference object size.

Recursive calculation of the memory occupied by the composite object should be noted that: the alignment of the fill is in each object as a unit, see the following diagram is easy to understand.

Now let's manually calculate how much memory the C object occupies, mainly three parts: the size of the C object itself + the size of the array object +b the size of the object.

No compression is turned on:

(4 + 8+4 (padding)) + (24+ 8*3) + (16+8) * = 152bytes

To turn on compression:

(4 + 4 +4 (padding)) + (16 + 4*3 +4 (Array object padding)) + (12+8+4 (b object padding)) *3= 128bytes

?

How much memory a Java object occupies

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.