Recently, I was reading the book JAVA Concurrent Programming Practice, which involves the JAVA memory model. Through the JAVA memory model, I came to the JVM memory structure logically. My cognition of THE JVM memory structure is still in the classroom in college, and I have not systematically studied this knowledge. So this time I have read the “In-depth Understanding of Java Virtual Machine JVM advanced features and best practices”, “Java Virtual Machine specification Java SE 8 edition” these two books on THE JVM memory structure of the part of the read, can be regarded as a new understanding of the JVM memory structure. The JVM memory structure refers to the fact that the Java virtual machine defines several types of run-time data areas that are used during the execution of the program. Some of these areas are created with the virtual machine starting up and destroyed with the virtual machine exiting, while others are created with the thread starting up and destroyed with the thread ending. The specific runtime data area is shown in the figure below:

In the Java Virtual Machine specification, five run-time data areas are defined, namely the Java heap, method area, virtual machine stack, local method area, and program counter, where the Java heap and method area are shared by threads. Let’s look at these five run-time data areas in detail.

Java Heap

The Java heap is an area of memory shared by all threads that is created at virtual machine startup, and a single JVM process has one and only one Java heap. The Java heap is used to store object instances and arrays, which means that objects in our code are stored there with the new keyword new. As a result, this has become the main activity camp of the garbage collector, so it has a nickname called the GC heap. According to the rules of the garbage collector, we can further divide the Java heap, as shown in the following figure:

We can divide the Java heap into two large modules: the new generation and the old generation. In the new generation, we can further divide it into Eden space, From Survivor space (S0), and To Survivor space (S1), one of which is empty. It is used to store live objects during GC. Old ages are objects that are still alive after multiple Minor GC’s or large objects, and FGC occurs in old ages.

The size of a Java heap can be dynamically controlled, and the size of a Java heap can be dynamically controlled. The size of a Java heap can be dynamically controlled, and the size of a Java heap can be dynamically controlled.

  • -xms: indicates the initial Heap value applied for when the JVM starts. The default Heap value is 1/64 of the operating system physical memory, for example, -xMS20m
  • -xmx: The maximum Heap value that the JVM can apply for. The default value is 1/4 of the physical memory, for example, -xmx20m. It is best to set -xms and -xmx to the same value to avoid memory reallocation after each garbage collection.
  • -xmn: sets the memory size of the new generation. -xmn sets NewSize to the same as MaxNewSize. We can also set these two parameters separately

An OOM exception will occur in the Java heap, and when there is enough space in the Java heap to complete the instance allocation and the heap cannot expand, the common OutOfMemoryError will be raised, as shown in the following figure:

If the JVM heap runs out of memory, can other threads continue to work? Personally, I think many of the answers are wrong. Those who are interested can study them.

Method Area

The Method Area, like the Java heap, is the only shared memory Area in the Java VIRTUAL machine. A method area is defined in the Java Virtual Machine specification as it stores structural information for each class, such as runtime constant pools, fields, method data, constructors, and bytecode content for common methods, as well as special methods used during class, instance, and interface initialization.

Method area at the virtual machine startup is created, although method area is logical part of the heap, but simple virtual machine implementation can choose in this area is not realize garbage collection and compression, method of area may not be continuous in the actual memory space, method for the capacity, you can be fixed, can also be dynamic extension with the execution of the program, And automatically shrinks when you don’t need too much space.

Above are all in the Java virtual machine specification, to look at the specific implementation, we often use the HotSpot virtual machine, for one, before JDK1.8 method area is also known as the permanent generation, will happen this way area we common Java. Lang. OutOfMemoryError: PermGen space exception, we can also control the size of the method area with the startup parameter:

  • -xx :PermSize Sets the minimum space
  • -xx :MaxPermSize Sets the maximum space

After JDK1.8, the HotSpot virtual machine has made some changes to the method area, completely removing the permanent generation, migrating the data stored in the permanent generation to the Java Heap or Metaspace, moving the method area to Metaspace, and moving string constants to the Java Heap. In other words, since JDK1.8, Metaspace is what we call a method section. Why make this change? Perhaps for two reasons:

  • Because the PermGen memory overflow, often causing annoying Java. Lang. OutOfMemoryError: PermGen, therefore the JVM developers hope this piece of memory would be a more flexible management, don’t often appear such OOM
  • Removing PermGen can facilitate fusion between HotSpot JVM and JRockit VM, as JRockit has no permanent generation.

We can also set parameters to control the size of Metaspace, mainly through the following commands:

  • -xx :MetaspaceSize: specifies the initial size (in bytes) of the metadata space allocated to the class. An excessively high MetaspaceSize value can prolong garbage collection time. After a garbage collection, the size of the class metadata space that causes the next garbage collection may increase.
  • -xx :MaxMetaspaceSize: The maximum amount of metadata space allocated to a class, beyond which Full GC is triggered. This value is unlimited by default, but depends on the size of system memory. The JVM changes this value dynamically.
  • -xx :MinMetaspaceFreeRatio: Indicates the minimum proportion of free class metadata after a GC to avoid increasing the size of metadata space. If not, garbage collection will result.
  • -xx :MaxMetaspaceFreeRatio: indicates the maximum proportion of free class metadata capacity that will result in garbage collection after a GC to avoid increasing the size of metadata space.

Java Virtual Machine (JVM Stacks)

Each Java virtual machine thread has its own private Java virtual machine stack, which is created at the same time as the thread, so it has the same life cycle as the thread. The Java virtual machine stack describes the memory model of Java method execution: Each method will create a stack frame when it is executed, which is used to store information such as local variable table, operand stack, dynamic link, method exit, etc. The process of each method from invocation to completion of execution corresponds to the process of a stack frame in the Java virtual machine stack.

The local variable table stores various basic data types known at compile time (Boolean, byte, CHAR, short, int, float, long, double), object references (reference type, which is not equivalent to the object itself, depending on the implementation of different virtual machines. It may be a reference pointer to the object’s starting address, a handle to the object or some other location associated with the object, and the returnAddress type (which points to the address of a bytecode instruction).

64-bit long and double data occupy two local variable slots, and the rest occupy only one. The memory space required for the local variable table is allocated at compile time. When entering a method, how much local variable space the method needs to allocate in the frame is completely determined, and the size of the local variable table does not change during the method run.

Java virtual machine stacks can be implemented to a fixed size or dynamically expanded and shrunk based on computation. With a fixed size, the size of the Java virtual machine stack for each thread can be selected independently at thread creation time. There are two types of exceptions that occur in the Java virtual machine stack, which are specified in the virtual machine specification:

  • The Java virtual machine will raise a StackOverflowError if the thread request allocates more stack capacity than the maximum allowed by the Java virtual machine stack.
  • An OutOfMemoryError will be raised if the Java virtual machine stack can be dynamically extended and there is not enough memory available when attempting to extend or when a new thread is created to create the corresponding Java virtual machine stack.

Program Counter Register

A program counter is also thread private, requiring only a small amount of memory. You can think of it as a line number indicator of the bytecode being executed by the current thread, in the conceptual model of the virtual machine (and only in the conceptual model, which various virtual machines may implement in more efficient ways). The bytecode interpreter works by changing the value of this counter to select the next bytecode instruction to be executed. Branch, loop, jump, exception handling, thread recovery and other basic functions need to be completed by this counter.

We know that in the case of multi-threading, not one thread is always executing, but multiple threads switch execution in turn, so in order to restore the thread to the correct execution position after switching, we need program counters to tell the thread which instruction to execute next. If the thread is executing a Java method, this counter records the address of the virtual machine bytecode instruction being executed. If the thread is executing a Natvie method, this counter is null (Undefined).

It is important to note that the program counter is the only area where the Java Virtual Machine specification does not specify any OutOfMemoryError cases.

Native Method Stacks

The Native Method stack is similar to the Java virtual machine stack except that the Java virtual machine stack services the execution of Java methods (i.e. bytecodes) by the virtual machine. The Native method stack serves Native methods used by the virtual machine. 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 (such as the Sun HotSpot VIRTUAL machine) that simply merge the local method stack with the virtual machine stack.

Like the Java virtual machine stack, the local method stack area throws StackOverflowError and OutOfMemoryError exceptions.

reference

  • In-depth Understanding of Advanced Features and Best Practices of the Java Virtual Machine JVM
  • Java VIRTUAL Machine Specification Java SE Version 8

The last

There are many articles about the memory structure of the JVM on the Internet, if there is a similar, please forgive me. The original is not easy, the code word is not easy, but also hope you support. If there are any mistakes in this article, I hope to put forward, thank you, welcome to scan the code to pay attention to the wechat public number: “Technology blog of Brother Flat head”, brother Flat head study together, progress together.