Introduction to the

The memory region, or JVM runtime data region, describes the partitioning of memory space.

The Java Memory Model (JMM) defines a direct abstraction between threads and main Memory. The JMM defines how a JVM works in computer Memory (RAM). If we want to understand concurrent programming in Java, we must first understand the Java Memory Model.

Java memory region

JVM layout after JDK8

1. Metaspace

Metacarspace replaces the previous PermGen.

Why remove the permanent generation?

A persistent generation is a pool that contains data needed by the JVM, such as classes or methods.

First of all, the target of memory reclamation in this area is mainly for constant pool reclamation and unloading of types. Generally speaking, the reclamation effect in this area is not satisfactory. Garbage collection for the permanent generation is tied to garbage collection for the old generation, and once one of the areas is occupied, both areas are collected.

Specify the size of the permanent build at startup using the -xx :MaxPermSize=xM argument. This value is static and will not be readjusted to change the runtime situation. If a string has a permanent generation, it is easy to run out of memory for the permanent generation or increase memory when there are more dynamically loaded classes. These are all easy to make OOM.

What is the metacarspace optimized for?

  • Size – The space occupied by the meta-space is dynamically recalculated based on the application requirements at run time. As more and more classes are loaded by the class loader, the amount of memory retained by the meta-space increases (or decreases when some class data is garbage collected).
  • Garbage collection – Once the metaspace limit is reached, the garbage collector on Metaspace starts working. For example, when the activity of the garbage collector on this space is too important, this could mean that the size specified by Metaspace is not sufficient for the actual situation, or there could be some memory leak.
  • No Klass – The meta space no longer contains KlassKlass and its derivatives. In the persistent generation, these objects are used to describe classes that describe the classes originally stored. This means that only the information of the original class is stored.

String constant pools, static variables, are moved to the heap. Runtime constant pools, type information, constants, fields, and methods are all moved into the meta-space.

2. Program Counter Register: The Program Counter Register is a line number indicator that records the bytecode executed by the current thread.

Because Java virtual machine multithreading is implemented by the way threads alternate and allocate processor execution time, only one processor core executes instructions in one thread at any given time.

Therefore, in order to recover to the correct execution position after thread switching, each thread needs to have an independent program counter, which is not affected by each other and 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 Native 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.

3. Java Vm stack:

The virtual machine Stack describes the memory model of Java method execution: each method execution creates a Stack Frame (the basic data structure of method execution) for storing information about local variables, operand stacks, dynamic links, method exits, and so on. The process of each method from invocation to completion corresponds to the process of a stack frame being pushed into and out of the virtual machine stack.

4. Local method stack:

The Native Method Stack is very similar to the virtual machine Stack. The difference is that the virtual machine Stack performs Java methods (that is, bytecode) services for the virtual machine, while the Native Method Stack serves the Native methods used by the virtual machine.

When threads start calling local methods, they enter a world that is no longer bound by the JVM. Local methods can access the data area of the virtual machine through the Java Native Interface (JNI), and even call registers, with the same capabilities and permissions as the JVM. When a large number of native methods occur, the JVM’s control over the system is bound to be weakened because of its black-box error messages. NativeheapOutOfMemory is still thrown by the local method stack in case of memory shortage.

5. 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.

Java memory model

The Java memory model is a concurrent model of shared memory, in which threads communicate implicitly through read-write shared variables (instance fields, static fields, and array elements in heap memory).

The Java Memory Model (JMM) controls communication between Java threads, determining when writes by one thread to a shared variable are visible to another thread.

Computer caching and cache consistency

Computers use caches between fast cpus and relatively slow storage devices as a buffer between memory and the processor. Copy the data needed for the operation to the cache so that the operation can run quickly. When the operation is finished, it is synchronized from the cache back to memory.

In a multi-processor system (or a single-processor, multi-core system), each processor core has its own cache, and they share the same Main Memory.

When the computation tasks of multiple processors all involve the same main memory area, the cache data of each processor may be inconsistent.

Therefore, each processor must follow some protocols when accessing the cache, and operate according to the protocols when reading and writing the cache to maintain the consistency of the cache.

VM main memory vs. working memory

The main goal of the Java memory model is to define the access rules for variables in the program, the low-level details of storing variables (variables shared by threads) into and out of memory in the virtual machine.

In the Java memory model, all variables are stored in the main memory, and each thread has its own working memory. All operations on variables must be carried out in the working memory by the thread, instead of reading or writing variables in the main memory.

Working memory here is a JMM abstraction, also known as local memory, which stores copies of shared variables that the thread reads/writes.

Just as each processor kernel has its own cache, each thread in the JMM has its own local memory.

Different threads cannot directly access variables in each other’s working memory, and there are generally two ways to communicate between threads, one is through message passing, and the other is shared memory. The communication between Java threads adopts shared memory. The interaction between threads, main memory and working memory is shown in the following figure:

The main memory, working memory and the Java heap, stack, method area in the Java memory area are not the same level of memory partition, the two are basically unrelated, if the two must be forced to correspond, then from the definition of variables, main memory, working memory, Main memory corresponds primarily to the object instance data portion in the Java heap, while working memory corresponds to a portion of the virtual machine stack.

Reference to www.cnblogs.com/czwbig/p/11…