Analysis of runtime data area of Java virtual machine
JVMmemorymodel
This article mainly introduces the runtime data areas described in the JVM specification. These areas are designed to store data used by the JVM itself or by programs running on the JVM.
Let's first overview the JVM, then introduce the bytecode, and finally introduce the different data regions.
Overview
As an abstraction of the operating system, JVM ensures that the same code behaves consistently on different hardware or operating systems.
For example:
For the basic type int, it is a 32-bit signed integer on a 16 bit / 32-bit / 64 bit operating system. Range from - 2 ^ 31 to 2 ^ 31-1
Whether the operating system or hardware is in large byte order or small byte order, ensure that the data in the memory stored and used by the JVM is in large byte order (read the high-order bytes first)
Different JVM implementations may differ somewhat, but they are generally the same.
The figure above is an overview of a JVM
The JVM interprets the bytecode generated by the compiler. Although JVM is the abbreviation of Java virtual machine, any language that can be compiled into bytecode can run based on JVM, such as Scala and groovy< �"/kf/ware/vc/" target="_blank" class="keylink" >vcD4NCjxwPs6qwcux3MPixrW3sbXEtMXFzEkvT6Os19a92sLru+Gxu2NsYXNzbG9hZGVyvNPU2LKiu7q05rW91MvQ0Mqxyv2+3cf41tC1xNK7uPbH+NPyo6zWqrXAvNPU2Mv8tcRjbGFzc2xvYWRlcrG7z/q72bvy1d9KVk3No9a51MvQ0KGjPC9wPg0KPHA+vNPU2LXE19a92sLrzai5/da00NDS/cfmKGV4ZWN1dGlvbiBlbmdpbmUpvfjQ0L3iys26zda00NA8L3A+DQo8cD7WtNDQ0v3H5tDo0qq05rSis8zQ8snPz8LOxKOsscjI57PM0PLWtNDQtb3ExNK70NCjrLv y1d/K/b7dvMbL47XE1tC85L3hufs8L3A+DQo8cD7WtNDQ0v3H5tKyuLrU8LSmwO3T67XXsuOy2df3z7XNs7XEvbu7pTwvcD4NCjxwPioquty24EpWTba8yrXP1sHLvLTKsbHg0uu5psTcKEpJVD1qdXN0IGluIHRpbWUpoaNKSVS+zcrHsNG+rbOj1rTQ0LXEtPrC6yjIyLXjtPrC6ymx4NLrs8mxvrXYtPrC6yhOYXRpdmUgQ29kZSmho7Tmt8VKSVSx4NLryfqzybT6wuu1xMf40/Kzxs6qPC9wPg0KPHA+tPrC67u6tObH+ChDb2RlIENhY2gpoaO8tMqxseDS67y8yvUo Sklukby2tpo1xmzhun / by0pwtbxe0nte3coqpc9wpg0kpggyiglkpq = = "stack based architecture" > stack based architecture
The JVM uses a stack based architecture. Although the stack is transparent to developers, it plays an important role or influence on the generated bytecode and JVM.
The program we developed will convert bits to low-level operations and store them in bytecode. In the JVM, it is mapped to operation instructions through operands. According to the JVM specification, the parameters required by the operation instruction are obtained from the operand stack.
Take an example of adding two numbers. This operation is called Iadd. The following is the process of 3 + 4 in bytecode
First, push 3 and 4 into the operand stack
Call Iadd instruction
The Iadd instruction pops two operands from the top of the operand stack
The result of 3 + 4 is pushed into the operand stack for later use
This approach is called stack based architecture. There are other ways to handle low-level operations, such as register based architecture.
Bytecode
Java bytecode is the result of converting java source code into a series of low-level operations. Each operation consists of one byte long opcode or operation code and zero or more byte long parameters (but the parameters used by most operations are obtained through the operand stack). One byte can represent 256 numbers, from 0x00 to 0xff. Up to java8, a total of 204 are used.
The following lists the different types of bytecode opcodes and their ranges and brief descriptions
Constants: pushes the value of the constant pool or a known value into the operand stack. 0x00 - 0x14
Loads: pushes the local variable value into the operand stack. 0x15 - 0x35
Stores: load value from operand stack to local variable 0x36 - 0x56
Stack: Processing operand stack 0x57 - 0x5f
Math: get value from operand stack for basic mathematical calculation 0x60 - 0x84
Conversions: converting between types 0x85 - 0x 93
Comaprisons: comparison of two values 0x94 - 0xa6
Controls: perform goto, return, loop and other control operations 0xa7 - 0xb1
References: allocate objects or arrays to get or check references of objects, methods and static methods. Static methods can also be called. 0xb2 - oxc3
Extended: Extended: operations from the others categories that were added after. From value 0xc4 to 0xc9
(I can't say what this means...)
Reserved: slots 0xca, oxfe, oxff are used inside the JVM implementation
These 204 operations are very simple, for example
Ifeq (0x99) determines whether the two values are equal
Iadd (0x60) adds two numbers
I2L (0x85) converts an int to bit long
Arraylength (0xbe) returns the length of the array
Pop (0x57) pops a value from the top of the operand stack
We need a compiler to create bytecode files. The standard Java compiler is javac in JDK.
The bytecode file of "test. Class" can be obtained through "javac test. Java". Bytecode file is binary. We can convert binary bytecode file into text form through javap
java -verbose Test. class
It can be seen that bytecode is not only a simple translation of Java code, but also includes:
Class. Constant pool is a JVM data area used to store class metadata, such as method names, parameter lists, and so on. When the JVM loads a class, the metadata is loaded into the constant pool
Provide specific location information of functions and tmall variables in bytecode through line number table or local variable table
Translation of Java code (including hidden parent class construction)
It provides more specific operations on the operand stack and more complete ways to pass and obtain parameters
The following is a simple description of the information stored in a bytecode file
Runtime data area
The runtime data area is a memory area designed to store data. This data is used internally by developers or JVMs.
Heap
The heap is created when the JVM starts and is shared by all JVM threads. All class instances and arrays are allocated to the heap (created by new).
The heap must be managed by a garbage collector, which is responsible for releasing objects created by developers and no longer used.
The garbage collection strategy is determined by the JVM implementation (for example, hotspot provides a variety of algorithms)
There is a maximum heap memory limit. If this value is exceeded, the JVM will throw an outofmemoy exception
Method area
The method area is also shared by all threads of the JVM. The same is created with JVM startup. The data stored in the method area is loaded from the bytecode by the classloader. These data will exist consistently during the operation of the application unless the classloader that loads them is destroyed or the JVM stops.
The method area stores the following data:
Class information (property name, method name, parent class name, excuse name, version, etc.)
Method and constructed bytecode
Runtime constant pool created when each class is loaded
The JVM specification does not force the method area to be implemented in the heap. Prior to Java 7, hotspot used an area called permgen to implement the method area. The persistent tape is adjacent to the heap (memory management is performed like the heap), and the default bit is 64MB
Starting with java8, hptspot uses separate local memory to implement the method area, named metadata area (Metaspace). The maximum free space of the metadata area is the available memory of the whole system.
If the method fails to apply for available memory, the JVM will also throw outofmemoryerror
Runtime constant pool the runtime constant pool is part of the method area. Because of the importance of running constant pool to metadata, it is described separately outside the method area in the Java specification. The runtime constant pool grows with loaded classes and interfaces.
Constant pools are a bit like syntax tables in traditional languages. In other words, when a class, method, or property is called, the JVM looks for the real address of the data in memory through the runtime constant pool. The runtime constant pool also contains constants of string literals or primitive types
PC (program counter) register (per thread) the PC register (per thread) each thread has its own PC (program counter) register, which is created together with thread creation. Each thread can only execute one method at a point in time, which is called the thread's current method. The PC register contains the address of the instruction currently being executed by the JVM (in the method area).
If the currently executed method is native, the value of the PC register is undefined
Virtual machine stack - Java virtual machine stacks per thread "> virtual machine stack (per thread) the Java virtual machine stacks (per thread) virtual machine stack stores multiple frames, so let's look at the next frame before describing the stack
Frames
A frame is a data structure that contains multiple data indicating the current method status that the thread is executing:
Operand stack: as mentioned earlier, bytecode instructions use the operand stack to pass parameters
Local variable array: this array contains all local variables within a scope of the currently executing method. This array can contain basic types, references, or return addresses. The size of the array of local variables is determined at compile time. The JVM uses local variables to pass parameters during method calls, and the local variable array of the called method is created through the operand stack of the calling method.
Runtime constant pool reference: refers to the constant pool of the currently executed method of the current class. The JVM uses constant pool references to signal true memory references.
Stack
Each JVM thread has a private JVM stack that is created simultaneously with the thread. The Java virtual machine stack stores frames. Each time a method is called, a frame is created and pushed into the virtual machine stack. When the method is executed, the frame will also be destroyed (whether the method is executed normally or throws an exception)
Only one frame is available during the execution of a thread. This frame is called the current frame.
Operations on local variables and operand stacks are usually combined with references to the current frame.
Let's take another example of addition
Within method a, frame a is the current frame and is located at the top of the virtual machine stack. At the beginning of the call to the add method, a new frame B is created and pushed into the virtual machine stack. Frame B becomes the new current frame.
The local variable array of frame B is filled with data in the operand stack of frame a. When the add method ends, frame B is destroyed and frame a becomes the current frame again. The result of the add method is pushed into the operand stack of frame a, so that method a can obtain the add result through the operand stack of frame a
summary
The above is all about the data area analysis of Java virtual machine runtime in this paper. I hope it will be helpful to you.
If there are deficiencies, please leave a message to point out.