preface

  • Learn about the JVM’s memory partitions and the general purpose and content of each region.
  • Learn more about memory failures and the use of some tools and some virtual machine parameters.

Memory partitioning and its contents

VM Stack

Stack thread specific

  • Stack frames are thread specific, and the JVM has multiple Stack frames in the Stack memory area.
  • The stack frame has a local variable table, which refers to objects in the heap by reference, or operates on objects in the heap by a handle.
  • References are not objects.

Program Counter Register

Program counter thread unique

  • Program counters are also thread private.
  • In simple terms, it is to record the execution of each thread of the program.
    • The CPU needs to know where the current thread went before it blocked so that it can continue execution where it paused last time.
  • The Program Counter Register is a small area of memory that can be thought of as a line number indicator of the bytecode being executed by the current thread.
  • In the conceptual model of virtual machine, bytecode interpreter works by changing the value of this counter to select the next bytecode instruction to be executed, and basic functions such as branch, loop, jump, exception handling, thread recovery and so on need to be completed by this counter.
  • Because multithreading in the Java virtual machine is implemented by the way threads alternate and allocate processor execution time, at any given moment, only one processor will execute instructions in one thread. Therefore, in order to restore the thread to the correct execution position after switching, each thread needs to have an independent program counter. Counters between threads do not affect each other and are stored independently. We call this kind of memory area as thread private memory.
  • If the thread is executing a Java method, this counter records the address of the virtual machine bytecode instruction being executed.
  • If the Native method is being executed, the value of this counter is null.
  • This memory region is the only one where the Java Virtual Machine specification does not specify any OutOfMemoryError cases.

Heap (Heap)

Heap thread sharing

  • For most applications, the Java heap is the largest chunk of memory managed by the Java Virtual machine.
  • The Java heap is an area of memory that is shared by all threads and is created when the virtual machine is started. The sole purpose of this memory area is to hold object instances.
  • The Java heap is the primary area managed by the garbage collector. From the point of view of memory collection, the Java heap can also be divided into: new generation and old generation, since the collector is basically a generational collection algorithm. More detailed are Eden space, From Survivor space, To Survivor space, etc.
  • From the perspective of memory Allocation, the Java heap shared by threads may have multiple Thread private Allocation buffers (TLabs).
  • The Java heap can be in a physically discrete memory space, as long as it is logically contiguous.

Method Area: Stores meta information. Permanent Generation, as of JDK 1.8, has been completely deprecated in favor of meta Spaces.

Method Area

  • Run-time constant pool.
  • Class metadata, (focus on blog comments) what exactly does the Java method area store?
  • The Method Area, like the Java heap, is an Area of memory shared by threads that stores information about classes loaded by the virtual machine, constants, static variables, code compiled by the just-in-time compiler, and so on.
  • Although the Java Virtual Machine specification describes the method area as a logical part of the Heap, it has an alias called non-heap, which is supposed to distinguish it from the Java Heap.
  • The “PermGen space” is the method area. There is a fundamental difference between a method area and a “PermGen space.” The former is a specification for the JVM, while the latter is an implementation of the JVM specification, and only HotSpot has the “PermGen space”.
  • The HotSpot VIRTUAL machine extends GC generation collection to the method area, or use persistent generation to implement the method area.
  • Such a HotSpot garbage collector can manage this part of memory as well as the Java heap, eliminating the need to write memory-management code specifically for the method area.
  • If the implementation method area belongs to the virtual machine implementation detail and is not subject to the virtual machine specification, it is not a good idea to implement the method area with permanent generation because it is prone to memory overflow.
  • Garbage collection is less common in this area, but it is not permanent when data enters the method area. The main targets of this area are constant pool reclamation and type offloading.
  • In Java8, the persistent generation is removed, and HotSpot in the methods area is implemented as the Metaspace metadata area, not in the virtual machine, but in local memory, storing the meta information of the class. Instead, the static variables of the Class (in the Class object) and the pool of runtime constants are placed in the heap.
  • The meta space uses direct memory and is dynamically expanded, with a default size of 21(20.75)M.
  • Where did Java permanent go?

Runtime Constant Pool

To be distinguished from constant pools in bytecode

  • Is part of the methods area. In addition to the description information, the Class file contains a constant pool for the various literals and symbolic references generated by the compiler, which will be stored in the runtime constant pool when the Class is loaded into the method area. In general, in addition to storing symbolic references described in Class files, translated direct references are also stored in the runtime constant pool.
  • An important feature of a runtime constant pool over a Class file constant pool is its dynamic nature. The Java language does not require constants to be generated only at compile time. It is possible to put new constants into the pool at run time, such as the Intern method of the String Class.

Direct Memory

  • 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, but it is also frequently used.
  • The NIO class in the JDK introduces a channel – and buffer-based IO approach that uses Native libraries to allocate out-of-heap memory directly, and then operates as a reference to that memory through a DirectByteBuffer object stored in the heap. This can significantly improve performance in some situations, avoiding copying data back and forth between the Java heap and Native heap. Direct memory allocation is not limited by the Java heap size, but by the total native memory.
  • Not managed by the Java virtual machine
  • Closely related to NIO.
  • The JVM operates directly on memory via DirectByteBuffer on the heap.

object

Create an object

  • new
  • reflection
  • clone
  • deserialization
  • Java creates objects in four ways.

Three steps to create an object

  • Create object instances in heap memory.
  • Assign initial values to object member variables.
  • Returns a reference to an object.
  • To break it down, when the virtual machine reaches a new instruction,
  • The first check is to see if the argument to the directive can locate a symbolic reference to a class in the constant pool, and to see if the symbolic reference represents a class that has been loaded, parsed, and initialized. If not, the class loading process is performed.
  • After the class load check passes, the virtual machine allocates memory for the new objects. The size of memory required by an object is 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. Assumption in the Java heap memory is absolutely neat, all used memory aside and free memory on the other side, there is a middle pointer as a cut-off point indicator, that allocates memory is just put the pointer to the free space to move over there a piece of equal distance and object size, this way of distribution collision is called a pointer.
  • If the memory in the Java heap is not tidy, the virtual machine must maintain a List of memory blocks that are available, find a large enough chunk of the List to allocate to object instances at allocation time, and update the records on the List. This allocation is called a Free List.
  • 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.
  • Besides partition space available, there is another issue to consider is the object creation in A virtual machine is very frequent behavior, even if only modify the position of A pointer is pointing to, in the case of concurrent is not thread-safe, is possible to allocate memory object A, pointer could change, Object B also uses the original pointer to allocate memory.
  • There are two solutions to solve this problem, one is to synchronize the action of allocating memory space, the other is to divide the action of allocating memory into different Spaces according to threads, that is, each thread allocates a small chunk of memory in the Java heap in advance, called the local thread allocation buffer TLAB.
  • Memory is allocated on the TLAB of the thread that allocates it, and synchronization locking is only required when the TLAB runs out and new TLabs are allocated.
  • After memory allocation is complete, the VM must initialize the allocated memory space to zero. Next, the virtual machine sets up the object as necessary, such as which class the object is an instance of and how to find the metadata for that class. This information is stored in the object header of the object. When this is done, from the virtual machine’s perspective, a new object has been created, but from the Java program’s perspective, the constructor has not yet been executed and the fields are still 0. So the execution of the new instruction is followed by execution of the constructor, etc., so that an object is actually generated.

Layout of objects in memory

  • The size of memory opened for heap open Settings is in virtual memory.
  • In the HotSpot VIRTUAL machine, the layout of objects stored in memory can be divided into three areas: object headers, Instance Data, and alignment Padding.
  • The object header contains two parts of information. The first part is used to store the runtime data of the object itself, such as hash code, GC generation age, lock status flag, and so on. The other part of the object header is the type pointer, the pointer to the object’s class metadata, which the virtual machine uses to determine which class the object is an instance of. Instance data is the valid information that an object actually stores and the content of various types of fields defined in program code. Both inherited from a parent class and defined in a subclass need to be documented. Fields of the same width are always assigned together. In this case, variables defined in the parent class appear before subclasses.
  • Alignment padding is not necessary, it is just a placeholder, the HotSpot VIRTUAL machine’s automatic memory management system requires that the object’s starting address be a multiples of 8 bytes, that is, the object’s size must be a multiples of 8 bytes, and the object’s header is exactly that. Therefore, when the object instance data part is not aligned, alignment padding is required to complete.

Object access location

  • Java programs need 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. There are two main ways to target using handles and direct Pointers.
  • The handle type:
    • If handle access is used, the Java heap will allocate a chunk of memory as the handle pool. Reference stores the handle address of the object, and the handle contains the specific address information of the instance data and the type data respectively.
    • The biggest advantage of using handles for access is that Reference stores a stable handle address, and only changes the instance data pointer in the handle when the object is moved. Reference itself does not need to be modified.
    • What is a handle in Java?

  • Direct pointer type, which HotSpot virtual machine is:
    • If direct pointer access is used, then the layout of the Java heap object must consider how to place information about the access type data, and the direct stored in Reference is the object address.
    • The biggest advantage of using direct pointer access is that it is faster and saves the time cost of a pointer location.

Memory overflow and memory leak

  • Demonstrates several types of memory overflow.
  • Use some VM parameters to modify the size of different MEMORY regions of the VM.

The difference between an overflow and a leak

  • For Java
    • Description The memory overflow failed to apply for sufficient memory.
    • Memory leaks. The allocated memory cannot be released.

Heap overflow

The command line:

  • JPS Check the Java process PID
  • Jstack -f Forces the dump

Dump dumps information.

  • Dump heap error
    • VM arguments: – XX: + HeapDumpOnOutOfMemoryError.
  • The Java heap is used to store object instances, and as long as you keep adding objects and making sure there is a reachable path between GC Roots and objects to avoid garbage collection, an OOM exception will occur after the maximum heap capacity is reached.
  • code
    • The VM Options: – Xms20m – Xmx20m – XX: + HeapDumpOnOutOfMemoryError (heap maximum minimum of 20 m)
public class HeapOOM { 
    static class OOMObject{}public static void main(String[] args) {
       List list = new ArrayList<>();
       while(true){ 
       list.add(newOOMObject()); }}}Copy the code

Stack overflow (virtual machine stack and local method stack)

For HotSpot, although the -xoss parameter (to set the stack size of the local method) exists, it is actually invalid, and the stack size is only set by the -xss parameter, which sets the stack size per thread

  • With respect to the virtual machine stack and the local method stack, two exceptions are described in the JVM specification:
    • StackOverflowError is thrown if the stack depth requested by the thread is greater than the maximum depth allowed by the virtual machine.
    • An OutOfMemoryError is thrown if the virtual machine cannot claim sufficient memory space while extending the stack.
  • code
public class StackSOF {
    private int stackLength = -1;
    public void stackLeak(a) {
        stackLength++;
        stackLeak();/ / recursion
    }
    public static void main(String[] args) {
        StackSOF sof = new StackSOF();
        try {
            sof.stackLeak();
        } catch (Throwable e) {
            System.out.println("stack length:" + sof.stackLength);
            throwe; }}}Copy the code

  • The operating system has a limit on the amount of memory that can be allocated to each process. 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 use up the remaining memory when creating threads.
  • If too many threads cause stack overflow,You can buy more threads by reducing the maximum heap and the stack size.
    • -Xss sets the stack size for each thread.

Metaspace overflow

  • Create dynamically created objects using cglib
    • Cglib dependencies need to be imported
  • code
    • Because the meta space is direct memory, it expands dynamically. So set the size of it, otherwise it’s hard to overflow.
    • Forget about permanent sections, not since Java 8.
    • -XX:MaxMetaspaceSize=10m
public class MetaSpaceTest {
    public static void main(String[] args) {
        while(true){
            Enhancer enhancer = new Enhancer();
            enhancer.setSuperclass(MetaSpaceTest.class);//set parent class, used to create subclasses
            enhancer.setUseCache(false);
            enhancer.setCallback((MethodInterceptor) (object,method,args1,proxy)
                    -> proxy.invokeSuper(object,args1));
            System.out.println("child will be created");
            enhancer.create();// Create an object}}}Copy the code

  • When there is no limit to the size of the meta space.
    • You can observe from JVisualVM that the classes are loaded in the meta-space.
    • It keeps multiplying.

Direct memory overflow

  • Direct memory can be specified using -xx :MaxDirectMemorySize, otherwise it defaults to the maximum Java heap size.
  • DirectByteBuffer also raises an OOM exception, but it does not actually ask the OS to allocate memory. Instead, it calculates that memory cannot be allocated, so it raises an exception manually. The real memory application is unsafe.allocatememory ().
  • code
    • VM Options: -XX:MaxDirectMemorySize=10m
public class DirectMemoryOOM {
    private static final int _1MB = 1024 * 1024;
    public static void main(String[] args) throws IllegalAccessException {
        Field unsafeField = Unsafe.class.getDeclaredFields()[0];
        unsafeField.setAccessible(true);
        Unsafe unsafe = (Unsafe) unsafeField.get(null);
        while(true) { unsafe.allocateMemory(_1MB); }}}Copy the code

I’m not going to show you any more tools

  • Description of the jstat command
  • jcmd
    • JCMD pid vm. flags: Displays startup parameters of the JVM
    • JCMD PID help: Lists the operations that the currently running Java process can perform
    • JCMD pid help jfr. dump: View options for specific commands
    • JCMD pid PerfCounter,print: View parameters related to JVM performance
    • JCMD pid VM. Uptime: Displays the startup duration of the JvM
    • JCMD pid GC.class_histogram: Views statistics about classes in the system
    • JCMD pid thread. print: Displays stack information about threads
    • Heap_dump filename: Exports the heap_dump file. The exported file can be viewed using JVisualVM
    • JCMD pid VM. System properties: Displays attributes of the JVM
  • JPS -L can look at pid.