In addition to Weibo, there is also WeChat
Please pay attention
WeChat public account
Shulou
2025-01-16 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Internet Technology >
Share
Shulou(Shulou.com)06/01 Report--
This article mainly introduces the JVM memory region of the example analysis, has a certain reference value, interested friends can refer to, I hope you can learn a lot after reading this article, the following let Xiaobian take you to understand.
JVM memory area
When writing programs, we often encounter problems such as OOM (out of Memory) and memory leaks. In order to avoid these problems, we must first have a specific understanding of the memory partition of JVM. JVM divides the memory into method area, virtual machine stack, local method stack, heap and program counter. The JVM runtime datazone is as follows:
Program counter
The program counter is the private area of the thread, which is easy to understand. Of course, each thread must have a counter to record the current execution of that instruction. It takes up a small amount of memory and can be thought of as a line number indicator of the bytecode executed by the current thread. If the thread is executing the Java method, this counter records the address of the virtual machine bytecode instruction that is executing; if the Native method is executed, the counter's value is Undefined. This memory region is the only one that does not specify any OutOfMemoryError conditions in the Java virtual machine specification.
Java virtual machine stack
Like program counters, the Java virtual machine stack is thread private. Its life cycle is the same as that of a thread. How to understand the virtual machine stack? Essentially, it's a stack. The elements stored inside are called stack frames, which seem to be very complex, but in fact, it is very simple! What is stored in it is the context of a function, specifically some data of the executed function. The data required by the executed function is nothing more than a local variable table (holding variables within the function), Operand stack (required to perform engine calculations), method exits, and so on.
Each time the execution engine calls a function, it creates a stack frame for that function and adds it to the virtual machine stack. To put it another way, from the call to the end of execution, each function actually corresponds to the stack and unstack of a stack frame.
Note two possible exceptions in this area: one is StackOverflowError, which is thrown when the stack depth requested by the current thread is greater than the depth allowed by the virtual machine. Making this exception is simple: recurring a function repeatedly to yourself will eventually result in a stack overflow error (StackOverflowError). Another exception is the OutOfMemoryError exception. When the virtual machine stack can be dynamically expanded (currently, most virtual machines can), OutOfMemoryError will be thrown if you cannot apply for enough memory. How to create a virtual machine stack OOM? refer to the code:
Public void stackLeakByThread () {
While (true) {
New Thread () {
Public void run () {
While (true) {
}
}
}. Start ()
}
}
This code is risky and may lead to the fake death of the operating system. Please use it carefully.
Local method stack
The role of the local method stack is similar to that of the virtual machine stack, except that the virtual machine stack serves to execute Java code methods, while the local method stack serves Native methods. Like the virtual machine stack, the local method stack throws StackOverflowError and OutOfMemoryError exceptions.
Java reactor
The Java heap is arguably the largest piece of memory in a virtual machine. It is the memory area shared by all threads, and almost all instance objects are stored in this area. Of course, with the development of the JIT compiler, the allocation of all objects on the heap has gradually become less "absolute".
The Java heap is the main area managed by the garbage collector. Since today's collectors basically use generation-by-generation collection algorithms, all Java heaps can be subdivided into the new generation and the old generation. In detail, the new generation is divided into Eden space, From Survivor space and To Survivor space. An OutOfMemoryError exception is thrown when the heap can no longer be extended.
Method area
The method area stores class information, constants, static variables, and so on. The method area is a shared area among threads, and it is easy to understand that when we write Java code, each line level can access static variable objects of the same class. Due to the use of the reflection mechanism, it is difficult for the virtual machine to speculate which type of information is no longer used, so it is difficult to recycle this area. In addition, this area is mainly for constant pool recycling, and it is worth noting that JDK1.7 has moved constant pools to the heap. Similarly, an OutOfMemoryError is thrown when the method area cannot meet the memory allocation requirements.
Manufacturing method area memory overflow, note that method area overflow must be in JDK1.6 and previous versions. As explained later, the virtual machine parameters-XXpermSize and-XX:MaxPermSize can be used to limit the method area size before execution.
List list = new ArrayList ()
Int I = 0
While (true) {
List.add (String.valueOf (I) .intern ())
}
A java.lang.OutOfMemoryError:PermGen space exception is thrown after running.
To explain, the intern () function of String is put into the constant pool if the current string does not exist in the constant pool. The above code keeps adding strings to the constant pool, which will eventually result in running out of memory and throwing the OOM of the method area.
Let's explain why the above code must be run before JDK1.6. As we mentioned earlier, after JDK1.7, the constant pool is put into the heap space, which leads to different functions of the intern () function. Let's take a look at the following code:
String str1 = new StringBuilder ("hua") append ("chao") .toString ()
System.out.println (str1.intern () = = str1)
String str2=new StringBuilder ("ja"). Append ("va"). ToString
System.out.println (str2.intern () = = str2)
The results of this code running on JDK1.6 and JDK1.7 are different. JDK1.6 result is: false,false, JDK1.7 result is true, false. The reason is: in JDK1.6, the intern () method will copy the string instance encountered for the first time to the constant pool, and return a reference to the string in the constant pool, while the string instance created by StringBuilder is on the heap, so it must not be the same reference and return false. In JDK1.7, intern no longer replicates the instance, and only the reference to the instance that first occurs is saved in the constant pool, so the reference returned by intern () is the same as the string instance created by StringBuilder. Why does the comparison to str2 return false? This is because the string "java" already exists when the class is loaded internally in JVM, which does not conform to the principle of "first occurrence", so false is returned.
Garbage collection (GC)
In JVM's garbage collection mechanism, judging whether an object is dead or not is not based on whether there are any references to it, but through reachability analysis. The references between objects can be abstracted into a tree structure, through the tree root (GC Roots) as the starting point, search down from these tree roots, the search chain is called reference chain, when an object is not connected to the GC Roots with any reference chain, it is proved that the object is unavailable, and the object will be judged as a recyclable object.
So which objects can be used as GC Roots? There are mainly the following:
1. The object referenced in the virtual machine stack (the local variable table in the stack frame).
two。 The object referenced by the class static property in the method area.
3. Objects referenced by constants in the method area
4. An object referenced by JNI (commonly known as the Native method) in the local method stack.
In addition, Java also provides soft references and weak references, which are objects that can be recycled by the virtual machine at any time. We can declare some objects that take up memory but may be used later, such as Bitmap objects, as soft references and weak references. Note, however, that every time you use this object, you need to display to determine whether it is null or not, so as to avoid errors.
Three common garbage collection algorithms
1. Mark-clear algorithm
First of all, the recyclable objects are marked through the reachability analysis, and then all the tagged objects are uniformly recycled. The marking process is actually the process of reachability analysis. This method has two shortcomings: efficiency problems, marking and clearing processes are both inefficient, and the other is space problems, which will produce a large number of discontinuous memory fragments after mark removal.
two。 Replication algorithm
In order to solve the problem of efficiency, the replication algorithm divides the memory into two blocks of the same size, using only one of them at a time. When this piece of memory is used up, the surviving objects are copied to another piece of memory. Then clean up the used memory at once. This allows only half an area to be garbage collected at a time, without considering memory fragmentation when allocating memory.
However, the cost is unacceptable and requires the sacrifice of general memory space. The study found that most of the objects are "life and death", so there is no need to install 1:1 scale to divide the memory space, but to divide the memory into a larger Eden space and two smaller Survivor space, each time use Eden space and a piece of Survivor space, the default ratio is Eden:Survivor=8:1. This is how the Cenozoic region is divided. Each instance is allocated between an Eden and a Survivor, and when reclaimed, the surviving objects are copied to the remaining Survivor. Only 10% of the memory will be wasted, but it will be very efficient. When the remaining Survivor memory runs out, you can go to the old memory for allocation guarantee. How to understand the allocation guarantee, in fact, when there is insufficient memory, go to the old era to allocate memory space, and then wait for the new generation of memory to recover, return the memory to the old era and maintain the Eden:Survivor=8:1 of the new generation. In addition, the two Survivor have their own names: From Survivor and To Survivor. The identities of the two are often swapped, that is, sometimes this piece of memory is allocated together with Eden, sometimes another piece of memory. Because they often copy each other.
3. Marking-finishing algorithm
The tag collation algorithm is simple: first mark the objects that need to be recycled, and then move all the surviving objects to one end of memory. This has the advantage of avoiding memory fragmentation.
Class loading mechanism
The whole life cycle of a class from being loaded into virtual machine memory to unloading out of memory includes seven stages: loading, verification, preparation, parsing, initialization, use and unloading.
The order of the five phases of loading, verification, preparation, initialization, and unloading is determined. The parsing phase is not necessarily: in some cases it can start after the initialization phase to support the runtime binding of Java.
With regard to initialization: the JVM specification makes it clear that initialization of a class must be performed in 5 cases (loading, verification, and preparation occurs naturally before that):
1. If you encounter new, getstatic, putstatic, invokestatic, if the class is not initialized, it must be initialized. These instructions are: new new object, read static variables, set static variables, and call static functions.
two。 When a reflection call is made to a class using the method of the java.lang.reflect package, if the class is not initialized, it needs to be initialized.
3. When initializing a class, if you find that the parent class is not initialized, you need to trigger the parent initialization first.
4. When the virtual machine starts, the user needs to develop an executing main class (the class that contains the main function), and the virtual machine initializes this class first.
5. However, when using JDK1.7-enabled dynamic language support, if the final parsing result of a MethodHandle instance is the method handle of REF_getStatic, REF_putStatic, and Ref_invokeStatic, and the corresponding class of the method handle is not initialized, its initialization should be triggered first.
It is also important to note that referencing the static fields of the parent class through the subclass does not cause the subclass to initialize:
Public class SuperClass {
Public static int value=123
Static {
System.out.printLn ("SuperClass init!")
}
}
Public class SubClass extends SuperClass {
Static {
System.out.println ("SubClass init!")
}
}
Public class Test {
Public static void main (String [] args) {
System.out.println (SubClass.value)
}
}
In the end, it only prints: SuperClass init!
For static variables, only the class that defines this field directly will be initialized, so referencing the static variable defined in the parent class through the subclass will only trigger the parent initialization, not the subclass initialization.
Referencing a class through an array definition does not trigger the initialization of this class:
Public class Test {
Public static void main (String [] args) {
SuperClass [] sca=new SuperClass [10]
}
}
Constants are stored in the caller's constant pool during compilation, and are essentially not directly referenced to the class that defines the constant, so the class initialization that defines the constant is not triggered. The example code is as follows:
Public class ConstClass {
Public static final String HELLO_WORLD= "hello world"
Static {
System.out.println ("ConstClass init!")
}
}
Public class Test {
Public static void main (String [] args) {
System.out.print (ConstClass.HELLO_WORLD)
}
}
There will be no ConstClass init in the above code!
Load
The loading process mainly does the following three things
1. Get the binary stream of this class through the fully qualified name of a class
two。 The static storage structure represented by the strong byte stream is transformed into the runtime data structure of the method area.
3. A java.lang.Class object representing this class is generated in memory as various data access entries for this class in the method area.
Verification
The main purpose of this stage is to ensure that the information contained in the byte stream of Class files meets the requirements of the current virtual machine and does not endanger the security of the virtual machine itself.
Prepare for
The preparation phase is the stage that formally allocates memory for class variables and sets the initial values of class variables, and the memory used by these variables is allocated in the method area. First of all, the memory allocation at this time includes only class variables (variables decorated by static), not instance variables. Instance variables are assigned in the java heap along with the object when the object is instantiated. Secondly, the initial value mentioned here "usually" is the zero value of the data type, assuming that a class variable is defined as
Public static int value=123
The initial value of the variable value after the preparation phase is 0, not 123, because no Java method has been executed, and the value value of 123 is stored in the class constructor () method after the program is compiled.
Analysis
The parsing phase is the process of replacing the symbolic reference of the constant pool in the virtual machine with a direct reference.
Initialization
The last step of class loading when the class is initialized. In the previous class loading process, except for the user can participate through the custom class loader in the loading phase, the rest of the actions are dominated and controlled by the virtual machine. When it comes to the initialization phase, the Java program code defined in the class is actually executed.
In the preparation phase, the variable has been assigned the initial value required by the system once, while in the initialization phase, the class variable is initialized according to the programmer's subjective plan made by the program. The initialization process is actually the process of executing the class constructor () method.
The () method is generated by the compiler automatically collecting the assignment actions of all class variables in the class and combining statements in static statement blocks. The order of collection is in the order in which statements appear in the source file. In a static statement block, only variables defined before the static statement block can be accessed, and variables defined after it can be assigned, but cannot be accessed. As follows:
Public class Test {
Static {
ITunes 0
System.out.print (I)
}
Static int iTunes 1
}
Unlike the class constructor (or instance constructor), the () method does not need to explicitly call the parent constructor, and the virtual machine ensures that the () of the parent class has been executed before the () method of the subclass is executed.
Class loader
With regard to the custom class loader, and the parent delegation model, I won't mention it here.
Thank you for reading this article carefully. I hope the article "sample Analysis of JVM memory area" shared by the editor will be helpful to you. At the same time, I also hope you will support us and pay attention to the industry information channel. More related knowledge is waiting for you to learn!
Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.
Views: 0
*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.
Continue with the installation of the previous hadoop.First, install zookooper1. Decompress zookoope
"Every 5-10 years, there's a rare product, a really special, very unusual product that's the most un
© 2024 shulou.com SLNews company. All rights reserved.