This article focuses on program counters in the Java memory model, virtual machine stacks, local method stacks, meta-spaces and heaps, and constant pools in the heap. Int ADD (int A, int B) function stack frame is obtained by decompiling javap class file in front, mainly analyzing the state change of local variable table, operand stack and program counter corresponding to JVM instruction in stack frame. And after JDK7 appeared to replace the permanent generation of metadata area, and analyzed the metadata area to replace the permanent generation of what are the benefits, mainly analyzes the impact of the string constant pool, and through the code to verify the superiority of metadata area compared to the permanent generation. JDK1.6 = JDK1.6 = JDK1.7+ = JDK1.6 = JDK1.6 = JDK1.6 = JDK1.6 = JDK1.6 = JDK1.6 = JDK1.6 = JDK1.6 = JDK1.6 = JDK1.6 = JDK1.6 = JDK1.6 The JDK1.7+ version pools references to objects on the heap directly.

Thread-private space

Program Counter Register

1. The bytecode line number indicator executed by the current thread (logic)

2. Change the counter value to select the next bytecode instruction to execute

3. There is a one-to-one relationship with threads, i.e., thread private

4. Count Java methods, if Native methods, the counter value is Undefined

5. Since only the instruction line numbers are counted, there is no memory leak

Java Virtual Machine Stack

The Java virtual machine stack is an in-memory model for the execution of Java methods. It contains multiple stack frames. What is inside the stack frame?

Local variable table, operation stack, dynamic link, return address, etc. The local variable table contains all variables during the execution of the method. Operand stack is mainly: push, push, copy, exchange, generate consumption variables.

public class ByteCodeSimple { public static int add(int a, int b){ int c = 0; c = a + b; return c; }}Copy the code

Run the javac command to compile the class file and then run the javap-verbose ByteCodeSimple. Class command to compile the following information:

Each blue rectangle represents the existence state of a stack frame, corresponding to the code above, there are a total of 7 stack frame state diagrams.

The iconst instruction simply pushes the operand 0 into the operand stack with input parameters 1,2 so the local variable table is 1 and 2. The istore instruction pops the element of the operand stack into the second variable of the local variator (because it is ISTore_2). Iload_0 pushes the 0th element of the local variator onto the operand stack, and then pushes the first element of the local variator onto the operand stack. The iADD instruction is then executed (remove the elements from the operand stack, add them, and put the result back on the top of the stack), and then the settlement result at the top of the stack is flipped onto the second variable in the local variable table, and then the second variable in the local variable table is placed on the operand stack again. Finally, the iReturn command is called to return the top element of the stack, and finally to destroy the stack frame.

So it can be seen that call a Java method is the need to set up the stack frame, if the layer number of recursive overmuch, beyond the depth limit of virtual machine stack, the result will be a Java. Lang. StackOverFlowError anomalies.

Another exception is Java. Lang. OutOfMemoryError, can trigger a Java virtual machine stack too much lang. An OutOfMemoryError, if you want to try, you can use the following code Windows please backup important documents before test

public void stackLeakByThread(){ while (true){ new Thread(() -> { while (true){ } }).start(); }}Copy the code

The native method stack, similar to the virtual machine stack, is primarily used for annotating native methods.

Space shared by threads

Let’s start with the difference between MetaSpace and permanent generation:

First, understand that the method area is just a specification for the JVM, and that MetaSpace and permanence are both implementations of the method area. After Java7, the string constant pool that was originally in the method area has been moved to the heap, and after JDK8, permanence has been replaced with MetaSpace. Not just in name:

1. What are the benefits of using local memory for the meta-space while the permanent generation uses memory for the JVM? The default class metadata allocation is limited only by the size of the local memory, which resolves the problem of insufficient space. All strings are stored in PermGen’s String constant pool, which resolves the problem of OutOfMemoryError in older JDK. By default, the JVM dynamically sets its size at runtime as needed.

2. String constant pool exists in permanent generation, which is prone to performance problems and memory overflow

Persistent generation introduces unnecessary complexity into the GC

4. Easy integration of HotSpot with other JVMS like Jrockit

The heap is the space for storing object instances (as well as arrays and string constant pools). The Java heap space can be in a physically discontinuous space, as long as the logic is continuous.

Three JVM performance tuning parameters

-xms, -xmx, -xss

-Xss specifies the stack size per thread. Generally 256K is sufficient. This configuration will affect the number of concurrent threads

-Xms Specifies the initial size of the heap. It is the size of the heap when the process is created. Once the initial capacity of the heap is divided, the heap will be automatically expanded

– Maximum size of the Xmx heap

Usually we set -xms to the same as -xmx, because memory jitter occurs when the heap is running out of memory, which affects the stability of the program.

Memory allocation policy

Static storage: Compile time determines the storage space requirements for each data target at run time

2. Stack storage: Data area requirements are unknown at compile time and determined before module entry at runtime, such as virtual machine stack

3, heap storage: compile time or run time module entry can not be determined, dynamic allocation, such as: object storage and destruction

The difference between heap and stack in the Java memory model

1. Management mode: the stack is released automatically, and the heap needs GC

2. Space size: The stack is smaller than the heap

Fragmentation correlation: stack fragmentation is much smaller than the heap

4. Allocation mode: stack supports static and dynamic allocation, while heap only supports dynamic allocation

5, efficiency: stack efficiency is higher than stacking

Intern () for different JDK versions

The intern method on the String puts the String into the String constant pool.

JDK6: Returns a reference to the string in the string constant pool if the string object was previously created when the intern method is called. Otherwise, the string object is added to the string constant pool and a reference to the string object is returned.

JDK6+ : returns a reference to the string in the string constant pool if the string object was previously created when the intern method is called. Otherwise, if the string object already exists in the Java heap, the heap reference to this object is added to the string constant pool and the reference is returned; If it does not exist in the heap, the string is created in the pool and a reference to it is returned.

We’ll start with an example of OutOfMemoryError: PermGen Space

Here is an example of a program that keeps putting random strings into a constant pool:

public class PermGenErrTest { public static void main(String[] args) { for (int i = 0; i < 1000; i++) { getRandomString(1000000).intern(); } System.out.println("success"); } private static String getRandomString(int length) { String str = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"; Random random = new Random(); StringBuilder stringBuilder = new StringBuilder(); for (int i = 0; i < length; i++) { int num = random.nextInt(62); stringBuilder.append(str.charAt(num)); } return stringBuilder.toString(); }}Copy the code

My JDK version selected JDK1.6 and configured the permanent generation to start at 6M and Max at 6M, and then kept adding strings to the constant pool. OutOfMemoryError: PermGen Space is displayed.

You can see that the execution completed successfully, and JDK1.7+ is not restricted by the MaxPerSize parameter because the permanent generation has been removed.

Intern () for different JDK versions

What will be output for JDK1.6? JDK1.7 +?

public class InternDifference { public static void main(String[] args) { String s1 = new String("a"); s1.intern(); String s2 = "a"; System.out.println(s1 == s2); String s3 = new String("a") + new String("a"); s3.intern(); String s4 = "aa"; System.out.println(s3 == s4); }}Copy the code

For JDK1.7+, the output is false, true

If String s = new String(” a “), the “a” will be created first and placed in the String constant pool. Then the new object will be placed in the heap. When s2 = “a”, the constant pool looks for the corresponding String, and if it does, returns a reference to it. So s1 == s2 compares the address of “a” in the string constant pool with the address of the object in the heap, which must be flase. String s3 = new String(” a “) + new String(” a “); It tries to put a reference to “aa”, that string object in the heap, into the constant pool and returns that reference. Since both are references to the same address, s3== S4 is true.

For JDK1.6, the output is false, false**, as shown below

When s1 = new String(” a “), “a” will be created first and placed in the String constant pool. Then the new object will be placed in the heap. When s2 = “a”, the constant pool looks for the corresponding String, and if it does, returns a reference to it. So s1 == s2 compares the address of “a” in the string constant pool with the address of the object in the heap, which must be flase. String s3 = new String(” a “) + new String(” a “); An attempt is made to put “aa”, the string object in the heap, into the constant pool and return a reference to “AA” from the string constant pool, but since the constant pool is equivalent to a copy of the object, when the reference is returned, the address is the permanent section, so S3 and S4 will not be equal.