This is the second day of my participation in Gwen Challenge

preface

Why should we learn about the JVM?

  1. Interview needs
  2. Essential skills for intermediate and advanced programmers
    • Project management, tuning needs
  3. Spirit of the geek
    • For example: garbage collection algorithm, JIT, underlying principles
  4. Well, it’s just fun.

The HotSpot VM is introduced

The HotSpot history

  • It was originally designed by a small company called Longview Technologies.
  • The company was acquired by Sun in 1997; Sun was acquired by Oracle in 2009.
  • In JDK1.3,HotSpot VM is called the default VM.

At present HotSpot occupies the absolute time position and dominates the martial arts.

  • In both the still widely used JDK6 and the heavily used JDK8, the default VIRTUAL machine is HotSpot.
  • Default virtual machine for Sun/Oracle JDK and OpenJDK.

It has applications ranging from server, desktop to mobile and embedded. HotSpot in its name refers to its HotSpot code detection technology.

  • The counter finds the code with the most compile value, triggering either just-in-time compilation or on-stack replacement
  • The compiler and interpreter work together to balance optimal program response time with optimal execution performance

Memory structure

For details on the class loading process, read the article Understanding the Java class loading mechanism in Depth

Let’s look at a detailed diagram of the JVM’s memory model

Program counter

The Program Counter Register is a small memory space that acts as a line number indicator of the bytecode being executed by the current thread. In the concept of virtual machine model (just the conceptual model, all kinds of virtual machine may be through some of the more efficient way to achieve), bytecode interpreter to work is by changing the counter value to select a need to be performed under the bytecode instruction, branches, loops, jumps, exception handling, thread to restore the basic function such as all need to rely on the counter.

Because multithreading in the Java VIRTUAL machine is implemented by the way threads alternate and allocate processor execution time, at any given moment, one processor (or kernel for multi-core processors) will execute instructions in only 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 “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 Natvie method is being executed, this counter value is null (Undefined).

This memory region is the only one where the Java Virtual Machine specification does not specify any OutOfMemoryError cases.

The JVM stack

Like program counters, the Java Virtual Machine Stack is thread-private and has the same lifetime as a thread. The virtual machine Stack describes the memory model of Java method execution: ** Each method execution creates a Stack Frame to store information about local variables, operation stacks, dynamic links, method exits, etc. Each method is called until the execution is complete, corresponding to the process of a stack frame in the virtual machine stack from the stack to the 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.

In the Java Virtual Machine specification, two exceptions are specified for this area: a StackOverflowError is thrown if the stack depth of a thread request is greater than the depth allowed by the virtual machine; If the virtual stack can scale dynamically (and most Java virtual machines currently do, although the Java Virtual Machine specification also allows fixed-length virtual stacks), an OutOfMemoryError will be thrown when sufficient memory cannot be allocated while scaling.

Local method stack

The Native Method stack is similar to the virtual machine stack, except that the virtual machine stack executes Java methods (i.e. bytecode) for the virtual machine, whereas the ** Native Method stack services the 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 virtual stack, the local method stack area throws StackOverflowError and OutOfMemoryError exceptions.

The Java heap

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, and almost all object instances are allocated memory here.

The Java heap is the primary area managed by the garbage collector and is often referred to as the “GC heap”. From the point of view of memory collection, the Java heap can be subdivided into: new generation and old generation; More detailed are Eden space, From Survivor space, To Survivor space, etc.

According to the Java Virtual Machine specification, the Java heap can be in a physically discontinuous memory space, as long as it is logically contiguous, like our disk space. When implemented, it can be either fixed size or extensible, but most current virtual machines are implemented as extensible (controlled by -xmx and -xMS).

OutOfMemoryError is thrown if there is no memory in the heap to complete the instance allocation and the heap can no longer be extended.

Methods area

The Method Area, like the Java heap, is an Area of memory shared by each thread. ** It is used to store information about classes that have been 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.

For developers who are used to developing and deploying applications on the HotSpot VIRTUAL machine, many prefer to refer to the method area as “Permanent Generation”, which is essentially not equivalent, simply because the HotSpot Virtual machine design team chose to extend GC Generation collection to the method area. Or to implement method sections using persistent generation.

The Java Virtual Machine specification is very relaxed about this area, in addition to the fact that, like the Java heap, it does not require contiguous memory and has the option of either fixed size or scalability, and optionally does not implement garbage collection. Garbage collection is relatively rare in this area, but it is not as “permanent” as the name of the permanent generation that data enters the method area. The target of memory reclamation in this area is mainly for constant pool reclamation and type unloading. Generally speaking, the “performance” of the reclamation in this area is not satisfactory, especially for type unloading, but the reclamation in this part of the area is indeed necessary.

According to the Java Virtual Machine specification, OutOfMemoryError is thrown when the method area cannot meet memory allocation requirements.

Method area changes in HotSpot

JDK version The difference between
Jdk1.6 and before There are permanent generations, where static variables are stored
jdk1.7 There are permanent generations, but the “permanent generation” has been gradually removed. The string constant pool, static variables are removed and stored in the heap
Jdk1.8 and after There is no permanent generation. Type information, fields, methods, constants are stored in the local memory meta-space, but the string constant pool, static variables are still in the heap

Run-time constant pool

  • The runtime constant pool is part of the method area;

  • The Constant Pool Table is used to store various literals and symbolic references generated at compile time. This part of the content is stored in the Constant Pool when the Class is loaded into the method area.

  • Each part of the Java virtual machine for the Class file (including constant pool) format has strict rules, each byte is used to store what kind of data must conform to the specification requirements will be on the virtual machine recognition, loading and execution, but for the runtime constant pool, the Java virtual machine specification, to do any detail requirement, Virtual machines that do not provide the above implementation can implement this memory area as they wish, but generally store translated direct references in the runtime constant pool as well as symbolic references described in the Class file.

  • Runtime constant pool relative to the Class file another important feature of their constant pool is dynamic, the Java language does not require constant can only be produced at compile time, that is, into the Class files is not preset constant pool area method can enter into the content of the runtime constant pool, runtime might also put new constants in a pool, One feature that developers use most often is the Intern () method of the String class.

  • Since the runtime constant pool is part of the method area and is naturally limited by the method area memory, OutOfMemoryError is thrown when the constant pool can no longer claim memory.

Permanent generation and meta-space

For a more detailed explanation, take a look at the memory structure of java7 and previous JVMS

The heap is connected to the method area, but this does not mean that the heap and the method area are together, they are still logically separate. But physically, they are contiguous chunks of memory.

In other words, the method area is continuous with Eden and the old age mentioned above.

PermGen

For programmers who are used to developing and deploying on a HotSpot virtual machine, many prefer to refer to the method area as a persistent generation.

In essence, the two are not equivalent, simply because Hotspot extends GC generation to the method area, or uses persistent generation to implement the method area. On other virtual machines there is no concept of a permanent generation. That is, the method area is the specification and the persistent generation is Hotspot’s implementation of that specification.

With these concepts in mind, let’s make a few more changes to the construction of the heap and method areas in Java7 and earlier versions.

For Java7 and previous versions of Hotspot, the method area is in the persistent generation. Meanwhile, the permanent generation and heap are isolated from each other, but they use continuous physical memory.

The permanent generation’s garbage collection is tied to the old generation, so whoever fills up triggers the permanent generation and the old generation’s garbage collection.

But some of the data stored in Java7’s persistent generation has already started moving to Java Heap or Native Memory. For example, Symbols are transferred to Native Memory. The string constant pool (Interned Strings) was moved to the Java Heap; Class statics are moved to the Java Heap.

Then, in Java8, times changed and Hotspot did away with persistent generation. The permanent generation has really become a permanent memory. The permanent generation parameters -xx :PermSize and -xx: MaxPermSize are also invalidated.

Metaspace

With Java8, 3.8% removed the permanent generation, so does that mean there’s no method section? Of course not. The method area is just a specification, but its implementation has changed.

In Java8, Metaspace takes the stage, and method areas live in Metaspace. At the same time, the meta space is no longer contiguous with the heap, but exists in Native memory.

Native memory, also known as C-heap, is used by the JVM’s own processes. GC is triggered when the Java Heap space is low, but not when the Native Memory space is low.

For the tweaks to Java8, we again tweaked the memory structure diagram.

Yuan space exists in local memory, means that as long as local memory enough, it won’t appear like permanent generation in Java. Lang. OutOfMemoryError: PermGen space such a mistake.

By default, the meta-space can make unlimited use of local memory, but to keep it from ballooning, the JVM also provides parameters to limit its use.

  • -xx :MetaspaceSize, the initial space quota of class metadata. Bytes trigger garbage collection for type offloading, and the GC adjusts the value. If a large amount of space is freed, the value is reduced. If very little space is freed, increase the value appropriately until it does not exceed MaxMetaspaceSize (if set).
  • -xx: MaxMetaspaceSize indicates the maximum space that can be allocated for class metadata. The default is unlimited.
  • -xx: MinMetaspaceFreeRatio, the minimum percentage of Metaspace free space capacity after GC to reduce garbage collection caused by allocating space for class metadata.
  • After – XX: MaxMetaspaceFreeRatio, GC, the biggest Metaspace the percentage of the remaining space capacity, reduced to class metadata release space to garbage collection.

The interviewer why use yuan | JVM space to replace the permanent generation?

  • Ostensibly to avoid OOM exceptions. Because it is common to use PermSize and MaxPermSize to set the size of the permanent generation to determine the upper limit of the permanent generation, it is not always possible to know how appropriate it should be, and it is easy to get OOM errors if you use the default.

  • When using meta-space, the number of classes of metadata that can be loaded is no longer controlled by MaxPermSize, but by the actual available space on the system.

  • The deeper reason is to merge HotSpot and JRockit code, JRockit never had a so-called persistent generation, nor did it require development operations to set the size of the persistent generation, but it worked fine. There are also no performance issues to worry about. In the tests covered, the application was up and running less than 1% slower, but this performance penalty is worth more security.

Direct memory

In the MEMORY model of the JVM, there is no direct memory, that is, this area of memory is not part of the JVM runtime data area, but it is frequently used because of the NIO package;

NIO (New Input/Output) is a New class added in JDK1.4, which introduces a channel and buffer based I/O mode. It can use the Native function library to allocate out-of-heap memory directly. This chunk of memory is then referenced and manipulated via DirectByteBuffer objects on the heap.

As you can see, the size of direct memory is not limited by the Size of the Java heap, or even by the size of JVM process memory. It is limited only by the size of the total native memory (RAM and SWAP or paging files) and the addressing space of the processor (the most common difference is the maximum addressing space limit for 32-bit / 64-bit CPUS).

conclusion

Reference for this article:

In-depth Understanding of Java Virtual Machine by Zhou Zhiming

Silicon Valley JVM complete tutorial, millions of playback, the peak of the entire network (Song Hongkang details Java virtual machine)