This is the 20th day of my participation in the Genwen Challenge
preface
It’s only when you get to a certain level where you need to understand the internal workings of the JVM, or high concurrency multithreading, where you’re writing code that has an internal impact and you want to optimize performance. When you want to learn more about how Java objects are in memory, how they are stored, or how much space each object takes up.
Memory formula
Java object memory layout = object Header + Instance Data + Padding.
Swallow the filling
Java object space is 8-byte aligned, that is, the number of bytes occupied by all Java objects must be a multiple of 8.
Shallow Size
-
The size of the memory used by the object itself, not including the object it references.
-
For non-array objects, the size is the sum of the size of the object and all of its member variables. Of course, this will also include some Java language features of the data storage unit.
-
For objects of array type, the size is the sum of the size of the array element objects.
Retained Size
Retained Size= The Size of the current object + the total Size of the object that can be directly or indirectly referenced. (Indirect reference: A->B->C, C is indirect reference)
In other words, Retained Size is the total amount of memory that can be freed from the Heap after the current object is GC.
However, the release also excludes objects that are directly or indirectly referenced by GC Roots. They won’t be Garbage for a while.
Next verify with JProfiler:
- Create an empty object and observe the memory usage of the empty object
public class TestObject {}
Copy the code
Object occupies 16byte memory, as shown in the figure:
conclusion
Generally, self-built empty objects occupy 16bytes of memory. 16bytes = 12bytes (Header) + 4bytes (Padding)
- Add an int attribute to TestObj to observe the memory usage of the object
public class TestObj {
private int i;
}
Copy the code
The object occupies 16 bytes of memory, as shown in the figure
conclusion
Int takes 4 bytes,16byte = 12byte(Header) + 4byte(int)+0byte(padding)
- Add a long attribute to TestObj to observe the memory usage of the object
public class TestObj {
private long i;
}
Copy the code
The object occupies 24B memory, as shown in the figure
conclusion
Long = 12(Header) + 8(long) + 4(Padding)
Other basic types can refer to the above self-verification, the principle is the same
Packaging type occupation
-
Wrapper classes (Boolean/Byte/Short/Character/Integer/Long/Double/Float) memory size = + the underlying object head size the size of the base data types.
-
A wrapper class, like any other reference class, produces a reference.
- Add an Integer attribute to TestObj to observe the memory usage of the object
public class TestObj {
private Integer i =128;
}
Copy the code
The object occupies 32B memory, as shown in the figure
conclusion
Integer occupies 16B, 32 = 12 (Header) + 16(Integer) + 4(reference)
Special: -128~127 in the constant pool, occupy only 4B, and do not generate reference.
- Add a Long attribute to TestObj to observe the memory usage of the object
public class TestObj {
private Long l = new Long(1);
}
Copy the code
The object occupies 40B memory, as shown in the figure
conclusion
40 = 12 (Header) + 24(Long) + 4(reference)
Other packaging types can refer to the above self-verification, the principle is the same
Primitive type array occupancy
On 64-bit machines, the object header of an array object takes up 24 bytes and 16 bytes with compression enabled. It takes up more memory than normal objects because it takes extra space to store the length of the array (normal 16b-12b).
The size of the array itself = the array object header + Length * The size of a single element
Add a char[] attribute to TestObj to observe the memory usage of the object
public class TestObj {
private char[] c = {'a'.'b'.'c'};
}
Copy the code
Char [] c occupies 40B memory, as shown in the figure
conclusion
Char [3] 24B, 24 = 40-16, 24 = 16(Header) + 3 * 2(char) + 2(Padding)
Encapsulating type array occupancy
An array of wrapper types requires more references to manage elements than an array of primitive types
The size of the array itself = the array object header + Length * The size of the reference pointer + Length * The size of the single element.
Add an Integer[] attribute to TestObj to observe the memory usage of the object.
public class TestObj {
private Integer[] i = {128.129.130};
}
Copy the code
Integer[] I occupies 80b memory, as shown in the figure
conclusion
Integer[3] uses 80B, 80 = 96-16, 80 = 16(Header) + 3 * 4(reference)+ 3 * 16(Integer) +4(padding)
Memory occupied by String
Add an empty String attribute to TestObj to observe the memory usage of the object.
public class TestObj {
private String s = new String("");
}
Copy the code
The object occupies 40B memory, as shown in the figure
conclusion
The String itself occupies 24 bytes, 24=40-16, i.e., empty “”, also requires 16 bytes.
Pay attention to
Why do I have String s = new String(“”)? Think for yourself, what would happen if you didn’t write?
A: If you write String s = “”, there will be no memory in the heap, and you will not see the space occupied by the String, you will see the following, and why, because of final.