In depth analysis of the memory prototype in Java and how it works

  • 2020-04-01 03:35:38
  • OfStack

This article explains how Java memory allocation works by analyzing the stack, heap, and constant pool.

Java virtual machine memory prototype

Register: in our program, we can't control the stack: store the basic types of data and object references, but the object itself is not stored in the stack, but is stored in the heap heap: stored in a static field produced by the new data, stored in the object using the static static members of the definition of constant pool: store constants of RAM storage: hard disk, such as permanent storage space.

Ii. Constant pool

A constant pool is defined at compile time and stored in the compiled. Some data in the class file. In addition to containing constant values (final) of various primitive types (such as int, long, and so on) and object types (such as String and array) defined in the code, it also contains symbolic references in the form of text, such as:

1. Fully qualified names of classes and interfaces;
2. Name and descriptor of the field;
Methods and names and descriptors.

The virtual machine must maintain a constant pool for each type that is loaded. A constant pool is an ordered set of constants used by this type, including direct constants (string,integer, and floating point constants) and symbolic references to other types, fields, and methods. For String constants, its value is in the constant pool. While the constant pool in the JVM exists as a table in memory. For the String type, there is a CONSTANT_String_info table of fixed length to store literal String values. With that said, you should have a fairly clear understanding of where the string values in the constant pool are stored. The constant pool is stored in the Method Area, not in the heap, while the program is executing.

Stack in Java memory allocation

The basic unit of stack is the frame (or stack frame) : each time a Java thread runs, the Java virtual machine allocates a Java stack to that thread. When executing a Java method, the thread pushes a frame onto the Java stack to store parameters, local variables, operands, intermediate results, and so on. When this method is finished, the frame pops out of the stack. All data on the Java stack is private, and no other thread can access that thread's stack data. Some of the basic types of variable data and object reference variables defined in the function are allocated in the function's stack memory. When a variable is defined in a block of code, Java allocates the memory space in the stack for that variable. When the variable exits the scope, Java automatically frees up the memory space allocated for that variable, which can be immediately used for other purposes.

Heap in Java memory allocation

The heap in the Java virtual machine is used to hold objects and arrays created by new. Memory allocated in the heap is managed by the Java virtual machine's automated garbage collection mechanism. In simple terms, as opposed to the stack, the heap is mainly used to store Java objects, the stack is mainly used to store object references... After an array or object is generated in the heap, you can also define a special variable in the stack whose value is equal to the first address of the array or object in the heap memory. This variable in the stack becomes a reference variable to the array or object. A reference variable is equivalent to a name for an array or object that can be used later in a program to access an array or object in the heap using a reference variable in the stack. A reference variable is equivalent to a name for an array or object.

Reference variables are ordinary variables that are allocated on the stack when defined and released when the program runs out of its scope. And array in the heap allocation and object itself, even if your application is to use the new array or object of the statement of a code block, array and object itself occupy memory will not be released, arrays and objects in the absence of reference variable pointing to it, to become a waste, not in use, but still too occupied memory space, in an uncertain time followed by the garbage collector (release) to collect. This is why Java takes up a lot of memory. In fact, a variable in the stack points to a variable in heap memory, which is a pointer in Java!

The Java heap is a runtime data area from which a class (object) allocates space. These objects are created by instructions such as new, newarray, anewarray, and multianewarray, and they do not require program code to be explicitly released. The heap is responsible for garbage collection, and the advantage of the heap is that you can dynamically allocate the memory size, and you don't have to tell the compiler in advance about the lifetime, because it dynamically allocates memory at run time, and the Java garbage collector automatically collects the data that is no longer used. The disadvantage is that access is slow because memory is allocated dynamically at run time.

The advantage of the stack is that access is faster than the heap, second only to registers, and stack data can be Shared. The disadvantage is that the size and lifetime of the data in the stack must be fixed and there is no flexibility. The stack mainly contains variable data of some primitive types (int, short, long, byte, float, double, Boolean, char) and object handles (references).

An important peculiarity of the stack is that the data stored in the stack can be Shared. Suppose we define:

Int a = 3; Int b = 3; The compiler first processes int a = 3; First it will create a reference to the variable a in the stack, then it will find out if there is a value of 3 in the stack, if not, it will store 3 in the stack, and then it will point a to 3. After the reference variable of b is created, b is directly pointed to 3 because there is already a value of 3 in the stack. Thus, both a and b are pointed to 3 at the same time.

Now, if I set a equal to 4; Then the compiler will search the stack again to see if there are 4 values. If not, it will store 4 in the stack and make a point to 4. If you already have it, point a directly to the address. So the change in a doesn't affect b.

Note that this sharing of data is different from the sharing of references to two objects pointing to one object at the same time, because in this case the modification of a does not affect b, it is done by the compiler, and it helps save space. When an object reference variable changes the internal state of that object, it affects another object reference variable.


Related articles: