preface

Summary of the JVM knowledge map:

An overview,

For Java developers, with the help of the virtual machine’s automatic memory management mechanism, there is no need to write the paired DELETE /free code for each new operation, which is less prone to memory leaks and memory leaks. However, this makes it very difficult to troubleshoot memory leaks and spills if you don’t know how your virtual machine is using memory.

Therefore, only when we understand each area of the VIRTUAL machine, the role of each area, the service object, etc., can we solve the memory problems when we encounter these problems.

Second, the runtime data area

During the execution of Java programs, the Java VIRTUAL machine divides the memory it manages into different data areas. Each of these areas has its own purpose and creation and destruction time. According to the Java Virtual Machine Specification, the memory managed by the Java Virtual Machine will contain the following run-time data areas.

Runtime data area

2.1- Program Counter Register

Overview: This area is a small memory space that can be thought of as a line number indicator of the bytecode being executed by the current thread.

Action: Selects the next bytecode instruction to execute by changing the value of the counter. Basic functions (branch, loop, jump, exception handling, thread recovery, etc.) depend on it to complete.

Features:

1. Thread private: Because Java virtual machine multithreading is implemented by switching threads in turn and allocating processor execution time, only one thread is executing at a time. Therefore, in order for threads to switch back to the correct execution position, each thread needs to have a separate program counter.

2. No memory overflow: If the thread is executing a Java method, this counter records the address of the vm bytecode instruction that is executing; If the Native method is being executed, this counter value is null (Undefined). This memory region is the only one that does not specify any OutOfMemoryError cases in the Java Virtual Machine program specification.

2.2-Java Virtual Machine Stacks

2.2.1-Java Virtual Machine Stack

Summary: Describes the memory model of Java method execution. The process of each method from invocation to execution corresponds to the process of a stack frame in the virtual machine stack and out of the stack.

Function: Store local variable table, operand stack, dynamic link, method exit and other information.

Features:

1. Thread private.

2. The life cycle is the same as that of a thread.

2.2.2- Local variation scale

Summary: Stores the various basic data types known at compile time (8), object references, returnAddress types (address pointing to a bytecode instruction).

Space: The 64-bit long and double types occupy two local variables (slots), and the rest occupy only one.

Allocation timing: Allocation is done at compile time. When entering a method, how much local variable space the method needs to allocate in the frame is completely determined. The size of the local variable table does not change during the method run.

Java memory is often divided into Heap memory and Stack memory, and the Stack referred to in this classification is the Java virtual machine Stack, or the local variable scale part of the virtual machine Stack.

2.2.3- Object references

Summary: The reference type, which is not the same as the object itself, may be a reference pointer to the object’s starting address, a handle representing the object, or some other location associated with the object.

2.2.4 abnormal –

2.3- Native Method Stack

Overview: Similar to the virtual machine stack, it is an area of memory that serves Native methods used by virtual machines.

The difference between:

O Vm stack: Java method (bytecode) execution services for virtual machines.

O Native method stack: serves Native methods used by VMS.

Exception: The vm stack is the same.

The virtual machine specification does not mandate the language, usage, or data structure of methods in the local method stack, so specific virtual machines are free to implement it. There are even virtual machines (e.g. Sun HotSpot VM) that simply merge the local method stack with the virtual machine stack.

2.4-Java Heap

Overview: For most applications, this area is the largest area of memory managed by the Java virtual machine.

Purpose: The sole purpose of this region is to hold object instances.

Features:

1. Shared by all threads.

2. Create the vm when the VM starts.

abnormal

Memory: The Java heap can be in a physically discrete memory space, as long as it is logically contiguous. In the implementation, it can be either fixed size or extensible. Currently, most virtual machines are implemented in terms of scalability (controlled by -xmx and -xMS).

Reminde � �

As JIT compilers evolve and escape analysis matures, optimization techniques such as on-stack allocation and scalar substitution will lead to subtle changes that make it less absolute that all objects are allocated on the heap.

2.5- Method Area

Overview: The Java Virtual Machine specification describes the method area as a logical part of the Heap, but it has an alias called non-heap to distinguish it from the Java Heap.

Function: Stores data (class information, constants, static variables, code compiled by the just-in-time compiler) that has been loaded by the virtual machine.

Features: Thread sharing.

abnormal

· Memory: The Java VIRTUAL Machine specification has very loose restrictions on method areas, with the option of not implementing garbage collection except that, like the Java heap, it does not require continuous memory space and can be fixed size or extensible.

Garbage collection is relatively rare in this region, where the main targets for memory collection are constant pool collection and type offloading.

2.6- Runtime Constant Pool

Overview: Part of the method area. In addition to the description of the Class (version, field, method, interface), the Class file also contains the constant pool.

Purpose: Used to store various literals and symbolic references generated by the compiler.

Dynamic: The Java language does not require a constant pool to be created only at compile time. That is, the contents of the constant pool in the Class file are not pre-loaded into the runtime constant pool in the method area. New constants can be added to the pool at run time.

abnormal

The Java Virtual Machine has strict rules about the format of each part of a Class file, including the constant pool. Each byte must be used to store the data type that the vm recognizes, loads, and executes, but the Java Virtual Machine specification does not specify any details about the runtime constant pool. Different vendor implementation virtual machines can implement this memory area according to their own requirements.

In general, in addition to storing symbolic references described in Class files, translated direct references are also stored in this area.

2.7- Direct Memory

Summary: It is not part of the run-time data area of the virtual machine, nor is it an area of memory defined in the Java Virtual Machine specification. However, this portion of memory is also frequently used and can cause OutOfMemoryError exceptions.

Function: NIO (New Input/Output) class is added in JDK1.4, introducing a Channel and Buffer based I/O mode, which can use the Native function library to allocate out-of-heap memory directly. It then operates through a DirectByteBuffer object stored in the Java heap as a reference to this memory. This can significantly improve performance in some scenarios because it avoids copying data back and forth between the Java heap and Native heap.

abnormal

Obviously, the allocation of native direct memory is not limited by the Size of the Java heap, but since it is memory, it is certainly limited by the size of native memory (including RAM and SWAP or paging size) and the addressing space of the processor. An exception occurs when the sum of memory areas exceeds the physical memory limit (both physical and operating system level limits).

HotSpot VIRTUAL machine object exploration

This section will illustrate the whole process of object allocation, layout, and access using the HotSpot VIRTUAL machine and the common memory region Java heap as examples.

3.1- Object creation

Overview: Java is an object-oriented programming language. Objects are created at any time during the running of a Java program. At the language level, creating an object is usually just a new keyword, while creating an object in a virtual machine involves the following steps.

3.1.1 – class loading

Overview: When a virtual machine receives a new instruction, it first checks to see if the instruction parameter can locate a symbolic reference to a class in the constant pool, and to see if the class represented by the symbolic reference has been loaded, parsed, and initialized. If not, the corresponding class loading process must be performed first.

3.1.2- Allocating memory

Summary: After class loading checks pass, the virtual machine will next allocate memory for the newborn objects. The size of memory required by an object is fully determined after the class is loaded, and the task of allocating space for an object is equivalent to dividing a certain size of memory from the Java heap.

Distribution method:

1. Bump the Pointer Given that memory in the Java heap is perfectly neat, with all used memory on one side and free memory on the other, and a pointer in the middle as an indicator of the cut-off point, the allocated memory is simply a matter of moving which pointer to the free side by an equal distance to the size of the object.

2. Free List: If the Java heap memory is not neat, used memory and free memory cross each other, that is simply no way pointer collision, the virtual machine, you must maintain a list of records on which memory blocks are available, at the time of distribution from the list to find a large enough space division to the object instance, and update the list of records.

The choice of allocation method depends on whether the Java heap is clean, which in turn depends on whether the garbage collector used has collation capabilities. Therefore, when collectors with Compact procedures such as Serial and ParNew are used, the allocation algorithm is pointer collision, whereas when collectors with mark-sweep algorithms such as CMS are used, the free list is usually used.

3.1.3- Synchronization control

Overview: object creation in A virtual machine is very frequent behavior, even if just modify the position of A pointer is pointing to, in the case of concurrent is not thread-safe, is possible to address object A distribution, pointer could modify, object B and use both the original pointer to allocate memory. There are two solutions to this problem.

Solution 1: Synchronize the memory space allocation on the VM. Configure the CENTRAL Authentication Service (CAS) server to ensure atomicity of the update operation.

Scheme 2: Allocate memory in different Spaces according to threads. Each Thread allocates a small block of memory in the Java heap in advance, called Thread Local Allocation Buffer (TLAB). Whichever thread needs to allocate memory is allocated on the TLAB of the thread, and synchronization locking is only required when the TLAB runs out and new TLabs are allocated. Use the -xx :+/ -usetlab parameter to set whether to UseTLAB.

3.1.4 – initialization

Summary: After memory allocation is complete, the virtual machine needs to initialize all allocated memory space to zero (excluding object headers). With TLAB, this process can be advanced to TLAB allocation time.

Function: To ensure that the instance fields of the object can be used directly in Java code without assigning initial values. The program can access the zero values corresponding to the data types of these fields.

3.1.5- Object Header

Overview: Next, the virtual machine sets up the object header data. (e.g., the instance class of the object, the address of the metadata information of the class, the hash code of the object, the GC generation age of the object)

3.1.6 – init

Summary: After the above steps are complete, a new object has been created from the perspective of the virtual machine, but from the perspective of the Java program, object creation has just begun, methods have not been executed, and all fields have zero values. In general, a new instruction is followed by a method that initializes the object as we wish before a real object is fully generated.

3.2- Memory layout of objects

In the HotSpot VIRTUAL machine, the layout of objects stored in memory can be divided into three areas.

3.2.1- Object Header

The HotSpot VIRTUAL machine object header contains two pieces of information, a Mark Word that stores its own runtime data and a type pointer.

Part ONE: Mark Word

Summary: Used to store runtime data of the object itself, such as (HashCode, GC generation age, lock status flag, thread holding lock, bias thread ID, bias timestamp), which is 32bit and 64bit in 32-bit and 64-bit virtual machines (without compression pointer enabled), respectively.

Memory: Objects need to store a lot of runtime data, which is beyond the scope of the 32-bit and 64-bit Bitmap structures. However, the object header information is an additional storage cost unrelated to the data defined by the object itself. Considering the space efficiency of the VIRTUAL machine, Mark Word is designed as a flexible data structure to store as much information as possible in a very small space. It reuses its storage space according to the state of the object.

The HotSpot VIRTUAL machine object header Mark Word table follows

Part two: Type Pointers

Overview: A pointer to an object’s class metadata that the virtual machine uses to determine which class instance the object is.

Reminder � �

Not all virtual machine implementations must keep type Pointers on object data; in other words, finding metadata for an object does not have to go through the object itself.

Array object: If the object is a Java array, there must also be a piece of data in the object header to record the length of the array, because the virtual machine can determine the size of the Java object from the metadata information of ordinary Java objects, but not from the array metadata.

3.2.2- Instance Data

Overview: This is the valid information that the object actually stores and the content of the various types of fields defined in the program code. Both inherited from a parent class and defined in a subclass need to be logged.

Storage order: The storage order of this part is affected by the order in which the vm allocation policy parameters (FieldsAllocationStyle) and fields are defined in the Java source code.

Longs/Doubles => INts =>shorts/chars => bytes/ Booleans => Oops (Ordinary Object Pointers) Fields of the same width are always assigned together. If this condition is met, variables defined in the parent class appear before subclasses.

If the CompactFields parameter is true (the default is true), narrower variables in the subclass may also be inserted into the gap between the parent class variables.

3.2.3- Align Padding

Summary: it is not necessarily there, it has no special meaning, it only serves as a placeholder.

How it works: Since HotSpot VM’s automatic memory management system requires that the object’s starting address be an integer multiple of 8 bytes, in other words, the object’s size must be an integer multiple of 8 bytes. The object header is exactly an integer multiple (1 or 2) of 8 bytes, so when the object instance data part is not aligned, it needs to be completed by alignment padding.

3.3- Object access location

Overview: Objects are created to use objects, and our Java program needs reference data on the stack to manipulate specific objects on the heap. Since the Java Virtual Machine specification only specifies a reference to an object, it does not define how the reference should locate and access the object in the heap, so object access is implementation-dependent. At present, there are two mainstream access methods.

Handle access: A block of memory will be allocated to the Java heap as a handle pool. Reference stores the handle address of the object, and the handle contains the specific address information of the instance data and type data of the object, as shown in the following figure.

Access objects through handles

Direct Pointers: The layout of the Java heap object must consider how to place information about the access type data, and the direct storage in Reference is the object address, as shown in the figure below.

Objects are accessed through direct Pointers

Comparison:

O Handle access: The biggest advantage of using handle access is that reference stores a stable handle address, which only changes the instance data pointer in the handle when the object is moved (a very common behavior in garbage collection). Reference itself does not need to be modified.

O Pointer access: The biggest benefit of using direct access is speed. It saves the time cost of a pointer location. Because object access is very frequent in Java, this kind of overhead can add up to a very significant execution cost.

Sun HotSpot uses the second approach for object access, but across the software development spectrum, it is also common for languages and frameworks to use handles for access.

OutOfMemoryError

In addition to the program counter, several other runtime areas of virtual machine memory are described by the Java Virtual Machine specification as having the possibility of an OutOfMemory (OOM) exception.

Objective:

1. Verify the storage contents of the various runtime areas described in the Java Virtual Machine specification with code.

2. When an actual memory overflow exception occurs, the system can quickly determine the memory overflow area based on the exception information.

3. Know what code might cause these areas to overflow and how to deal with it.

The VM Args set

Eclipse IDE: Debug Configurations => JavaApplication => YoungGenGC => Arguments write in VM Arguments (the writing Arguments start with – and are separated by Spaces).

Console: Write directly after Java commands.

I run in the Mac system, using IDEA to configure, the steps are as follows.

1. Open Run Configurations (gain ⌃ + ⌥ + R select 0) or (gain + ⇧ + A type Run select Run… .

2. Click and open VM Options.

3. Write the VM startup parameters.

4. Apply and Run.

4.1 Java heap overflow

· Overview: Java heaps are used to store object instances. As long as objects are constantly created and GC Roots have a reachable path to the objects to avoid garbage collection, overflow exceptions will occur after the maximum heap capacity is reached.

Test environment:

Test code:

Running results:

Analysis: The OOM exception of Java heap memory is a common memory overflow exception in real-time applications. When a Java heap memory leak, Java exception stack information. Lang. OutOfMemoryError will follow further prompt Javaheap space.

The solution

1. Heap dump snapshot: In order to resolve the exception in this area, the usual method is to analyze the heap Dump through the Memory image analysis tool first. The focus is to confirm whether the object in Memory is necessary, that is, to distinguish between a Memory Leak and a Memory Overflow.

2. Memory leak: Further check the leak object’s reference chain to CG Roots with the tool to see what path the memory leak object is associated with GC Roots and causes the garbage collector to fail to reclaim them automatically. With the type information of the leaked object and the reference chain information of GC Roots, the location of the leaked code can be more accurately located.

3. Memory overflow: If there is no leak, in other words, the objects in memory really must be alive, then you should check the heap parameters of the virtual machine (-Xmx and -xMS), and the physical memory objects of the machine to see if they can be scaled up, and code to see if some objects are too long in life and hold state. Try to reduce the memory consumption of the program’s runtime.

4.2- Vm stack and local method stack overflow

Overview: Since there is no distinction between virtual machine stacks and local method stacks in the HotSpot virtual machine, for HotSpot, the -xoos parameter (setting the local method stack size) exists but is actually invalid and the stack size is only set by the -xSS parameter. With respect to the virtual machine stack and the local method stack, two exceptions are described in the Java Virtual Machine specification.

This seems more serious, but there is some overlap: too little memory or too much used stack space when the stack space can no longer be allocated is essentially just two ways of describing the same thing.

2 – StackOverflowError

Test environment: In this test, the scope of the test is limited to operating in a single thread.

1. The -xss parameter is used to reduce the stack memory capacity. As a result, SOF exception is thrown, and the output stack depth decreases accordingly.

2. A large number of local variables are defined to increase the length of the local variable table in this method stack. As a result, the output stack depth shrinks when SOF exceptions are thrown.

The test code

The results

In a single thread, a StackOverflowError is raised when memory cannot be allocated, either because the stack frame is too large or because the vm stack size is too small.

However, there is no correlation between overflow exceptions and whether the stack space is large enough, or rather, in this case, the more memory allocated for each thread’s stack, the more likely it is to generate overflow exceptions.

Understanding: The operating system allocates a limited amount of memory to each process, and the virtual machine provides parameters to control the maximum amount of memory in the Java heap and method area. Remaining memory -Xms (maximum heap capacity) -MaxPermSize (maximum method area capacity), the program counter memory consumption is small and can be ignored.

If the memory consumed by the virtual machine process itself is not counted, the remaining memory is split between the virtual machine stack and the local method stack. The larger the stack size allocated to each thread, the smaller the number of threads that can be created, and the easier it is to run out of memory when creating threads.

Exploration: The error stack can be read when SOF exceptions occur, making it relatively easy to locate the problem. Also, if you use the virtual machine default, the stack depth is in the 1000-2000 range in most cases (because each method pushes a different frame size) and should be sufficient for normal method calls (including recursion).

However, if you run out of memory by setting up multiple threads, you can only replace more threads by reducing the maximum heap and stack size without reducing the number of threads or replacing the 64-bit VIRTUAL machine.

4.2.2 OutOfMemoryError –

The test environment

Test code: create thread cause memory overflow exception

 

The results

4.3- Method area and runtime constant pool overflow

Overview: Because the runtime constant pool is part of the method area, overflow tests for the two areas are done together.

String. Intern () is a Native method that returns a String representing the String in the pool if the String constant pool already contains a String equal to the String. Otherwise, the String contained in this String is added to the constant pool and a reference to this String is returned.

In JDK1.6 and earlier, because constant pools are allocated within permanent generations, we can indirectly limit the capacity of the constant pool by limiting the size name of the method area by -xx :PermSize and -xx :MaxPermSize.

4.3.1 OutOfMemoryError –

The test environment

The test code

 

The results

Analysis: As you can see from the run results, the runtime constant pool overflows and the message followed by OutOfMemoryError is PermGenspace, indicating that the runtime constant pool is part of the method area (the persistent generation in the HotSpot VIRTUAL machine).

4.3.2-String Constant pool test

Running this program with JDK1.7 will not yield the same result, and the while loop will continue. A more interesting implication can be derived from the implementation of this string constant pool.

The test code

Analysis:

O JDK1.6: will get two false, while running in JDK1.7 will get one true and one false.

The reason for the difference is that the JDK1.6 method intern() copies the first encountered string instance into the persistent generation and returns a reference to the same string instance in the persistent generation. String instances created by StringBuilder are on the Java heap, so they must not be the same reference and will return false

The o JDK1.7: Intern () implementation no longer copies the instance, but records the first instance reference in the constant pool, so intern() returns the same reference as the string instance created by StringBuilder.

The str2 comparison returns false because the Java string is already present before stringBuilder.toString () is executed and has a reference to it in the string constant pool, which does not comply with the first-occurrence rule. The computer software string is the first occurrence and therefore returns true.

4.3.3- Test design ideas

The method area is used to store information about the Class, such as the Class name, access modifiers, constant pools, field descriptions, method descriptions, and so on. The basic idea for testing these areas is to generate a large number of classes at runtime to fill the method area until it overflows. Alternatively, classes can be generated dynamically (such as GeneratedConstorAccessor and dynamic proxy for reflection) using the Java SE API directly.

4.3.4 – summary

Method area overflow is a common memory overflow exception. The criteria for a class to be collected by garbage collector are very strict.

In applications where a large number of classes are generated dynamically, special attention needs to be paid to Class reclamation. Such scenes in addition to the above mentioned procedure using additional bytecode enhancement and dynamic language, common: a large number of JSP or dynamically generated JSP file application (JSP to run for the first time need to compile Java classes), based on the OSGi application (even if the same class files, be different loader loads will be seen as different classes), etc.

4.4- Native direct memory overflow

Summary: DirectMemory capacity can be specified by -xx :MaxDirectMemorySize. If not specified, the default is the same as the Maximum Java heap size (specified by -xmx). The following test code overrides the DirectByteBuffer class. Retrieving Unsafe instances directly for memory allocation via reflection. (The getUnsafe() method of the Unsafe class restricts returning instances only to the bootstrap class loader, meaning that the designers wanted only classes in rt.jar to use Unsafe’s functionality.)

DirectByteBuffer does not actually ask the operating system to allocate memory. Instead, it calculates that the memory cannot be allocated, so it manually throws an exception. The actual method of allocating memory is unfase.allocatememory ().

The test code

The results

If the Heap Dump file is too small after OOM, and NIO is used directly or indirectly, you should consider checking for this cause. If the Heap Dump file is too small after OOM, NIO is used directly or indirectly.

Java memory area and memory overflow exception

1. An overview of the

For Java developers, with the help of the virtual machine’s automatic memory management mechanism, there is no need to write the paired DELETE /free code for each new operation, which is less prone to memory leaks and memory leaks. However, this makes it very difficult to troubleshoot memory leaks and spills if you don’t know how your virtual machine is using memory.

Therefore, only when we understand each area of the VIRTUAL machine, the role of each area, the service object, etc., can we solve the memory problems when we encounter these problems.

2. Run time data area

During the execution of Java programs, the Java VIRTUAL machine divides the memory it manages into different data areas. Each of these areas has its own purpose and creation and destruction time. According to the Java Virtual Machine Specification, the memory managed by the Java Virtual Machine will contain the following run-time data areas.

Runtime data area

2.1- Program Counter Register

Overview: This area is a small memory space that can be thought of as a line number indicator of the bytecode being executed by the current thread.

Action: Selects the next bytecode instruction to execute by changing the value of the counter. Basic functions (branch, loop, jump, exception handling, thread recovery, etc.) depend on it to complete.

Features:

1. Thread private: Because Java virtual machine multithreading is implemented by switching threads in turn and allocating processor execution time, only one thread is executing at a time. Therefore, in order for threads to switch back to the correct execution position, each thread needs to have a separate program counter.

2. No memory overflow: If the thread is executing a Java method, this counter records the address of the vm bytecode instruction that is executing; If the Native method is being executed, this counter value is null (Undefined). This memory region is the only one that does not specify any OutOfMemoryError cases in the Java Virtual Machine program specification.

2.2-Java Virtual Machine Stacks

2.2.1-Java Virtual Machine Stack

Summary: Describes the memory model of Java method execution. The process of each method from invocation to execution corresponds to the process of a stack frame in the virtual machine stack and out of the stack.

Function: Store local variable table, operand stack, dynamic link, method exit and other information.

Features:

1. Thread private.

2. The life cycle is the same as that of a thread.

2.2.2- Local variation scale

Summary: Stores the various basic data types known at compile time (8), object references, returnAddress types (address pointing to a bytecode instruction).

Space: The 64-bit long and double types occupy two local variables (slots), and the rest occupy only one.

Allocation timing: Allocation is done at compile time. When entering a method, how much local variable space the method needs to allocate in the frame is completely determined. The size of the local variable table does not change during the method run.

Java memory is often divided into Heap memory and Stack memory, and the Stack referred to in this classification is the Java virtual machine Stack, or the local variable scale part of the virtual machine Stack.

2.2.3- Object references

Summary: The reference type, which is not the same as the object itself, may be a reference pointer to the object’s starting address, a handle representing the object, or some other location associated with the object.

2.2.4 abnormal –

2.3- Native Method Stack

Overview: Similar to the virtual machine stack, it is an area of memory that serves Native methods used by virtual machines.

The difference between:

O Vm stack: Java method (bytecode) execution services for virtual machines.

O Native method stack: serves Native methods used by VMS.

Exception: The vm stack is the same.

The virtual machine specification does not mandate the language, usage, or data structure of methods in the local method stack, so specific virtual machines are free to implement it. There are even virtual machines (e.g. Sun HotSpot VM) that simply merge the local method stack with the virtual machine stack.

2.4-Java Heap

Overview: For most applications, this area is the largest area of memory managed by the Java virtual machine.

Purpose: The sole purpose of this region is to hold object instances.

Features:

1. Shared by all threads.

2. Create the vm when the VM starts.

abnormal

Memory: The Java heap can be in a physically discrete memory space, as long as it is logically contiguous. In the implementation, it can be either fixed size or extensible. Currently, most virtual machines are implemented in terms of scalability (controlled by -xmx and -xMS).

Reminde � �

As JIT compilers evolve and escape analysis matures, optimization techniques such as on-stack allocation and scalar substitution will lead to subtle changes that make it less absolute that all objects are allocated on the heap.

2.5- Method Area

Overview: The Java Virtual Machine specification describes the method area as a logical part of the Heap, but it has an alias called non-heap to distinguish it from the Java Heap.

Function: Stores data (class information, constants, static variables, code compiled by the just-in-time compiler) that has been loaded by the virtual machine.

Features: Thread sharing.

abnormal

Exception types

The conditions

StackOverflowError

There is no

OutOfMemoryError

This exception is thrown when the method area cannot meet memory allocation requirements.

Memory: The Java VIRTUAL Machine specification is very relaxed about method areas, with the option of not implementing garbage collection except that, like the Java heap, it does not require contiguous memory space and can be either fixed size or extensible.

Garbage collection is relatively rare in this region, where the main targets for memory collection are constant pool collection and type offloading.

2.6- Runtime Constant Pool

Overview: Part of the method area. In addition to the description of the Class (version, field, method, interface), the Class file also contains the constant pool.

Purpose: Used to store various literals and symbolic references generated by the compiler.

Dynamic: The Java language does not require a constant pool to be created only at compile time. That is, the contents of the constant pool in the Class file are not pre-loaded into the runtime constant pool in the method area. New constants can be added to the pool at run time.

abnormal

Exception types

The conditions

StackOverflowError

There is no

OutOfMemoryError

Because it is part of the method area, it is limited by the method area memory. This exception is thrown when the constant pool can no longer claim memory.

The Java Virtual Machine has strict rules about the format of each part of a Class file, including the constant pool. Each byte must be used to store the data type that the vm recognizes, loads, and executes, but the Java Virtual Machine specification does not specify any details about the runtime constant pool. Different vendor implementation virtual machines can implement this memory area according to their own requirements.

In general, in addition to storing symbolic references described in Class files, translated direct references are also stored in this area.

2.7- Direct Memory

Summary: It is not part of the run-time data area of the virtual machine, nor is it an area of memory defined in the Java Virtual Machine specification. However, this portion of memory is also frequently used and can cause OutOfMemoryError exceptions.

Function: NIO (New Input/Output) class is added in JDK1.4, introducing a Channel and Buffer based I/O mode, which can use the Native function library to allocate out-of-heap memory directly. It then operates through a DirectByteBuffer object stored in the Java heap as a reference to this memory. This can significantly improve performance in some scenarios because it avoids copying data back and forth between the Java heap and Native heap.

abnormal

Obviously, the allocation of native direct memory is not limited by the Size of the Java heap, but since it is memory, it is certainly limited by the size of native memory (including RAM and SWAP or paging size) and the addressing space of the processor. An exception occurs when the sum of memory areas exceeds the physical memory limit (both physical and operating system level limits).

3.HotSpot VIRTUAL machine object exploration

This section will illustrate the whole process of object allocation, layout, and access using the HotSpot VIRTUAL machine and the common memory region Java heap as examples.

3.1- Object creation

Overview: Java is an object-oriented programming language. Objects are created at any time during the running of a Java program. At the language level, creating an object is usually just a new keyword, while creating an object in a virtual machine involves the following steps.

3.1.1 – class loading

Overview: When a virtual machine receives a new instruction, it first checks to see if the instruction parameter can locate a symbolic reference to a class in the constant pool, and to see if the class represented by the symbolic reference has been loaded, parsed, and initialized. If not, the corresponding class loading process must be performed first.

3.1.2- Allocating memory

Summary: After class loading checks pass, the virtual machine will next allocate memory for the newborn objects. The size of memory required by an object is fully determined after the class is loaded, and the task of allocating space for an object is equivalent to dividing a certain size of memory from the Java heap.

Distribution method:

1. The Pointer collision (Bump the Pointer) : suppose the Java heap memory is absolutely neat, all used memory aside and free memory on the other hand, there is a middle Pointer as a cut-off point indicator, the allocated memory which is just the Pointer to the free move over there a and the object is equal to the size of the distance.

2. Free List: If the Java heap memory is not neat, used memory and free memory cross each other, that is simply no way pointer collision, the virtual machine, you must maintain a list of records on which memory blocks are available, at the time of distribution from the list to find a large enough space division to the object instance, and update the list of records.

The choice of allocation method depends on whether the Java heap is clean, which in turn depends on whether the garbage collector used has collation capabilities. Therefore, when collectors with Compact procedures such as Serial and ParNew are used, the allocation algorithm is pointer collision, whereas when collectors with mark-sweep algorithms such as CMS are used, the free list is usually used.

3.1.3- Synchronization control

Overview: object creation in A virtual machine is very frequent behavior, even if just modify the position of A pointer is pointing to, in the case of concurrent is not thread-safe, is possible to address object A distribution, pointer could modify, object B and use both the original pointer to allocate memory. There are two solutions to this problem.

Solution 1: Synchronize the memory space allocation on the VM. Configure the CENTRAL Authentication Service (CAS) server to ensure atomicity of the update operation.

Scheme 2: Allocate memory in different Spaces according to threads. Each Thread allocates a small block of memory in the Java heap in advance, called Thread Local Allocation Buffer (TLAB). Whichever thread needs to allocate memory is allocated on the TLAB of the thread, and synchronization locking is only required when the TLAB runs out and new TLabs are allocated. Use the -xx :+/ -usetlab parameter to set whether to UseTLAB.

3.1.4 – initialization

Summary: After memory allocation is complete, the virtual machine needs to initialize all allocated memory space to zero (excluding object headers). With TLAB, this process can be advanced to TLAB allocation time.

Function: To ensure that the instance fields of the object can be used directly in Java code without assigning initial values. The program can access the zero values corresponding to the data types of these fields.

3.1.5- Object Header

Overview: Next, the virtual machine sets up the object header data. (e.g., the instance class of the object, the address of the metadata information of the class, the hash code of the object, the GC generation age of the object)

3.1.6 – init

Summary: After the above steps are complete, a new object has been created from the perspective of the virtual machine, but from the perspective of the Java program, object creation has just begun, methods have not been executed, and all fields have zero values. In general, a new instruction is followed by a method that initializes the object as we wish before a real object is fully generated.

3.2- Memory layout of objects

In the HotSpot VIRTUAL machine, the layout of objects stored in memory can be divided into three areas.

3.2.1- Object Header

The HotSpot VIRTUAL machine object header contains two pieces of information, a Mark Word that stores its own runtime data and a type pointer.

Part ONE: Mark Word

Summary: Used to store runtime data of the object itself, such as (HashCode, GC generation age, lock status flag, thread holding lock, bias thread ID, bias timestamp), which is 32bit and 64bit in 32-bit and 64-bit virtual machines (without compression pointer enabled), respectively.

Memory: Objects need to store a lot of runtime data, which is beyond the scope of the 32-bit and 64-bit Bitmap structures. However, the object header information is an additional storage cost unrelated to the data defined by the object itself. Considering the space efficiency of the VIRTUAL machine, Mark Word is designed as a flexible data structure to store as much information as possible in a very small space. It reuses its storage space according to the state of the object.

The HotSpot VIRTUAL machine object header Mark Word table follows

Part two: Type Pointers

Overview: A pointer to an object’s class metadata that the virtual machine uses to determine which class instance the object is.

Reminder � �

Not all virtual machine implementations must keep type Pointers on object data; in other words, finding metadata for an object does not have to go through the object itself.

Array object: If the object is a Java array, there must also be a piece of data in the object header to record the length of the array, because the virtual machine can determine the size of the Java object from the metadata information of ordinary Java objects, but not from the array metadata.

3.2.2- Instance Data

Overview: This is the valid information that the object actually stores and the content of the various types of fields defined in the program code. Both inherited from a parent class and defined in a subclass need to be logged.

Storage order: The storage order of this part is affected by the order in which the vm allocation policy parameters (FieldsAllocationStyle) and fields are defined in the Java source code.

Longs/Doubles => INts =>shorts/chars => bytes/ Booleans => Oops (Ordinary Object Pointers) Fields of the same width are always assigned together. If this condition is met, variables defined in the parent class appear before subclasses.

If the CompactFields parameter is true (the default is true), narrower variables in the subclass may also be inserted into the gap between the parent class variables.

3.2.3- Align Padding

Summary: it is not necessarily there, it has no special meaning, it only serves as a placeholder.

How it works: Since HotSpot VM’s automatic memory management system requires that the object’s starting address be an integer multiple of 8 bytes, in other words, the object’s size must be an integer multiple of 8 bytes. The object header is exactly an integer multiple (1 or 2) of 8 bytes, so when the object instance data part is not aligned, it needs to be completed by alignment padding.

3.3- Object access location

Overview: Objects are created to use objects, and our Java program needs reference data on the stack to manipulate specific objects on the heap. Since the Java Virtual Machine specification only specifies a reference to an object, it does not define how the reference should locate and access the object in the heap, so object access is implementation-dependent. At present, there are two mainstream access methods.

Handle access: A block of memory will be allocated to the Java heap as a handle pool. Reference stores the handle address of the object, and the handle contains the specific address information of the instance data and type data of the object, as shown in the following figure.

 

Access objects through handles

Direct Pointers: The layout of the Java heap object must consider how to place information about the access type data, and the direct storage in Reference is the object address, as shown in the figure below.

Objects are accessed through direct Pointers

Comparison:

O Handle access: The biggest advantage of using handle access is that reference stores a stable handle address, which only changes the instance data pointer in the handle when the object is moved (a very common behavior in garbage collection). Reference itself does not need to be modified.

O Pointer access: The biggest benefit of using direct access is speed. It saves the time cost of a pointer location. Because object access is very frequent in Java, this kind of overhead can add up to a very significant execution cost.

Sun HotSpot uses the second approach for object access, but across the software development spectrum, it is also common for languages and frameworks to use handles for access.

OutOfMemoryError

In addition to the program counter, several other runtime areas of virtual machine memory are described by the Java Virtual Machine specification as having the possibility of an OutOfMemory (OOM) exception.

Objective:

1. Verify the storage contents of the various runtime areas described in the Java Virtual Machine specification with code.

2. When an actual memory overflow exception occurs, the system can quickly determine the memory overflow area based on the exception information.

3. Know what code might cause these areas to overflow and how to deal with it.

The VM Args set

Eclipse IDE: Debug Configurations => JavaApplication => YoungGenGC => Arguments write in VM Arguments (the writing Arguments start with – and are separated by Spaces).

Console: Write directly after Java commands.

I run in the Mac system, using IDEA to configure, the steps are as follows.

 

1. Open Run Configurations (gain ⌃ + ⌥ + R select 0) or (gain + ⇧ + A type Run select Run… .

2. Click and open VM Options.

3. Write the VM startup parameters.

4. Apply and Run.

4.1 Java heap overflow

· Overview: Java heaps are used to store object instances. As long as objects are constantly created and GC Roots have a reachable path to the objects to avoid garbage collection, overflow exceptions will occur after the maximum heap capacity is reached.

Test environment:

Test code:

Running results:

Analysis: The OOM exception of Java heap memory is a common memory overflow exception in real-time applications. When a Java heap memory leak, Java exception stack information. Lang. OutOfMemoryError will follow further prompt Javaheap space.

The solution

1. Heap dump snapshot: In order to resolve the exception in this area, the usual method is to analyze the heap Dump through the Memory image analysis tool first. The focus is to confirm whether the object in Memory is necessary, that is, to distinguish between a Memory Leak and a Memory Overflow.

2. Memory leak: Further check the leak object’s reference chain to CG Roots with the tool to see what path the memory leak object is associated with GC Roots and causes the garbage collector to fail to reclaim them automatically. With the type information of the leaked object and the reference chain information of GC Roots, the location of the leaked code can be more accurately located.

3. Memory overflow: If there is no leak, in other words, the objects in memory really must be alive, then you should check the heap parameters of the virtual machine (-Xmx and -xMS), and the physical memory objects of the machine to see if they can be scaled up, and code to see if some objects are too long in life and hold state. Try to reduce the memory consumption of the program’s runtime.

4.2- Vm stack and local method stack overflow

Overview: Since there is no distinction between virtual machine stacks and local method stacks in the HotSpot virtual machine, for HotSpot, the -xoos parameter (setting the local method stack size) exists but is actually invalid and the stack size is only set by the -xSS parameter. With respect to the virtual machine stack and the local method stack, two exceptions are described in the Java Virtual Machine specification.

This seems more serious, but there is some overlap: too little memory or too much used stack space when the stack space can no longer be allocated is essentially just two ways of describing the same thing.

2 – StackOverflowError

Test environment: In this test, the scope of the test is limited to operating in a single thread.

1. The -xss parameter is used to reduce the stack memory capacity. As a result, SOF exception is thrown, and the output stack depth decreases accordingly.

2. A large number of local variables are defined to increase the length of the local variable table in this method stack. As a result, the output stack depth shrinks when SOF exceptions are thrown.

The test code

The results

In a single thread, a StackOverflowError is raised when memory cannot be allocated, either because the stack frame is too large or because the vm stack size is too small.

However, there is no correlation between overflow exceptions and whether the stack space is large enough, or rather, in this case, the more memory allocated for each thread’s stack, the more likely it is to generate overflow exceptions.

Understanding: The operating system allocates a limited amount of memory to each process, and the virtual machine provides parameters to control the maximum amount of memory in the Java heap and method area. Remaining memory -Xms (maximum heap capacity) -MaxPermSize (maximum method area capacity), the program counter memory consumption is small and can be ignored.

If the memory consumed by the virtual machine process itself is not counted, the remaining memory is split between the virtual machine stack and the local method stack. The larger the stack size allocated to each thread, the smaller the number of threads that can be created, and the easier it is to run out of memory when creating threads.

Exploration: The error stack can be read when SOF exceptions occur, making it relatively easy to locate the problem. Also, if you use the virtual machine default, the stack depth is in the 1000-2000 range in most cases (because each method pushes a different frame size) and should be sufficient for normal method calls (including recursion).

However, if you run out of memory by setting up multiple threads, you can only replace more threads by reducing the maximum heap and stack size without reducing the number of threads or replacing the 64-bit VIRTUAL machine.

4.2.2 OutOfMemoryError –

The test environment

Test code: create thread cause memory overflow exception

 

The results

4.3- Method area and runtime constant pool overflow

Overview: Because the runtime constant pool is part of the method area, overflow tests for the two areas are done together.

String. Intern () is a Native method that returns a String representing the String in the pool if the String constant pool already contains a String equal to the String. Otherwise, the String contained in this String is added to the constant pool and a reference to this String is returned.

In JDK1.6 and earlier, because constant pools are allocated within permanent generations, we can indirectly limit the capacity of the constant pool by limiting the size name of the method area by -xx :PermSize and -xx :MaxPermSize.

4.3.1 OutOfMemoryError –

The test environment

The test code

The results

  

Analysis: As you can see from the run results, the runtime constant pool overflows and the message followed by OutOfMemoryError is PermGenspace, indicating that the runtime constant pool is part of the method area (the persistent generation in the HotSpot VIRTUAL machine).

4.3.2-String Constant pool test

Running this program with JDK1.7 will not yield the same result, and the while loop will continue. A more interesting implication can be derived from the implementation of this string constant pool.

The test code

Analysis:

O JDK1.6: will get two false, while running in JDK1.7 will get one true and one false.

The reason for the difference is that the JDK1.6 method intern() copies the first encountered string instance into the persistent generation and returns a reference to the same string instance in the persistent generation. String instances created by StringBuilder are on the Java heap, so they must not be the same reference and will return false

The o JDK1.7: Intern () implementation no longer copies the instance, but records the first instance reference in the constant pool, so intern() returns the same reference as the string instance created by StringBuilder.

The str2 comparison returns false because the Java string is already present before stringBuilder.toString () is executed and has a reference to it in the string constant pool, which does not comply with the first-occurrence rule. The computer software string is the first occurrence and therefore returns true.

4.3.3- Test design ideas

The method area is used to store information about the Class, such as the Class name, access modifiers, constant pools, field descriptions, method descriptions, and so on. The basic idea for testing these areas is to generate a large number of classes at runtime to fill the method area until it overflows. Alternatively, classes can be generated dynamically (such as GeneratedConstorAccessor and dynamic proxy for reflection) using the Java SE API directly.

4.3.4 – summary

Method area overflow is a common memory overflow exception. The criteria for a class to be collected by garbage collector are very strict.

In applications where a large number of classes are generated dynamically, special attention needs to be paid to Class reclamation. Such scenes in addition to the above mentioned procedure using additional bytecode enhancement and dynamic language, common: a large number of JSP or dynamically generated JSP file application (JSP to run for the first time need to compile Java classes), based on the OSGi application (even if the same class files, be different loader loads will be seen as different classes), etc.

4.4 – Native direct memory overflow

Summary: DirectMemory capacity can be specified by -xx :MaxDirectMemorySize. If not specified, the default is the same as the Maximum Java heap size (specified by -xmx). The following test code overrides the DirectByteBuffer class. Retrieving Unsafe instances directly for memory allocation via reflection. (The getUnsafe() method of the Unsafe class restricts returning instances only to the bootstrap class loader, meaning that the designers wanted only classes in rt.jar to use Unsafe’s functionality.)

DirectByteBuffer does not actually ask the operating system to allocate memory. Instead, it calculates that the memory cannot be allocated, so it manually throws an exception. The actual method of allocating memory is unfase.allocatememory ().

The test code

The results

If the Heap Dump file is too small after OOM, and NIO is used directly or indirectly, you should consider checking for this cause. If the Heap Dump file is too small after OOM, NIO is used directly or indirectly.

The last

I have arranged a: JVM related information documents, Spring family bucket series, Java systematic information (including Java core knowledge, interview topics and the latest 20 years of the Internet, e-books, etc.) friends who need to pay attention to the public number [procedures Yuan Small wan] can be obtained.