When we create a Java object with new, the virtual machine takes care of all the memory allocation. But what does a Java object actually look like in memory? Where is its instance object? How to handle the inheritance relationship? These questions are usually unfamiliar to everyone. This article attempts to visualize the memory structure of objects and classes by way of graphical examples.
1. Java object headers
The ultimate parent of all Java classes is java.lang.Object, so when we create a Java Object, we must instantiate java.lang.Object. Java.lang.Object has a corresponding C++ class in ART ::mirror::Object. The “mirror” in the namespace indicates that there is a corresponding relationship between java.lang. Object and Java classes. When we create a Java Object with New Object(), we get the simplest memory structure in memory space.
Only two C++ fields are stored in this memory structure: klass_ and monitor_, which correspond to shadow$_klass_ and shadow$_monitor_ in java.lang.Object, respectively. These eight bytes, often referred to as object headers, are the space that all Java objects must allocate.
Here is an actual art:: Mirror ::Object data. Note that kVTableLength and hash_CODE_seed are static fields of art:: Mirror ::Object and do not exist in Java objects.
2. JavaClass object
(class)
Java provides a java.lang.Class Class, instances of which represent classes or interfaces in a running program. Fields in the instance record metadata for the class or interface.
When we want to create an instance (Class object) of a java.lang.Class Class, we have three options:
- Class.forName(“className”)
- MyClass.class
- obj.getClass()
If we have a class com.hangl.example, then com.hangl.example. class represents the class object of that class. In ART, the creation of objects of this Class is also an instantiation of ART :: Mirror ::Class.
Since java.lang.Class inherits from java.lang.Object, art:: Mirror ::Class also inherits from art:: Mirror ::Object. So an art:: Mirror ::Class object also contains klass_ and Monitor_ fields in its memory structure.
Here is the actual art:: Mirror ::Class data. Similarly, kClassWalkSuper kPrimitiveTypeSizeShiftShift and kPrimitiveTypeMask is art: : mirror: : a Class of static field, so you don’t exist in the Java Class object.
Java.lang.object. class and java.lang.class.class
4. Store the instance field
As mentioned earlier, the simplest Java object takes only 8 bytes and stores two fields: klass_ and Monitor_. These 8 bytes are also called object headers and are required for every object.
Most objects need to store instance fields of the class in addition to the object header. Instance fields of each Class vary in size, which is determined by LinkClass during the Class load phase. These instance fields are stored immediately following the object header, so the true memory footprint of an object is usually shown below.
5. Storage location of static fields
The information a class has can be divided into two parts, one is metadata, such as how many instance fields the class has, how many virtual methods, etc., is descriptive information. The other part is the value of the static field. Metadata can be represented through art:: Mirror ::Class objects, with static fields following.
This memory structure is very similar to a Java object, with metadata in the top half and field values in the bottom half. Except that the metadata for objects are klass_ and Monitor_, while the metadata for classes are class_loader_ and methods_, etc. Field values in an object are instance fields, and field values in a class are static fields.
Note, however, that the static fields of each class are unique in memory, so subclasses do not need to store the static fields of their parent class. This is different from instance fields.