当前位置:网站首页>Deep understanding of JVM - JVM memory model

Deep understanding of JVM - JVM memory model

2022-06-25 10:09:00 Southern kingdom_ Love

We know , Computer CPU Interaction with memory is the most frequent , Memory is our cache , User disk and CPU Interaction , and CPU Running faster and faster , The disk is far behind CPU Reading and writing speed , Just designed memory , Users buffer users IO Waiting leads to CPU Waiting cost of , But as the CPU The development of , Memory reading and writing speed is far behind CPU Reading and writing speed , therefore , To settle this dispute ,CPU Manufacturers in each CPU Cache is added on , To relieve the symptoms , therefore , Now? CPU The interaction with memory becomes the following .

  Again , According to Moore's law , We know single core

CPU It is impossible for the dominant frequency of to increase indefinitely , To think a lot of new capabilities , Multiple processors are needed to work together , Intel The president's Beiruite kneeling event marks the arrival of the multi-core era .

 

  Cache based storage interaction solves the contradiction between processor and memory , It also introduces new questions : Cache consistency issues . In a multiprocessor system , Each processor has its own cache , And they share the same memory ( The main memory is ,

main memory  Main memory ), When multiple processor operations involve the same memory area , It is possible for cache inconsistency to occur . To solve this problem , You need to follow some protocols when each processor is running , At runtime, these protocols need to be used to ensure the consistency of data . Such agreements include MSI、MESI、MOSI、Synapse、Firely、DragonProtocol etc. . As shown in the figure below

 

 Java

The access operations defined in the virtual machine memory model are basically consistent with those processed by the physical computer !

 

 Java

The multithreading mechanism enables multiple tasks to execute processing at the same time , All threads share JVM Memory area main memory, Each thread has its own working memory , When a thread interacts with a memory area , Copy data from main memory to working memory , Then let the thread handle ( opcode + Operands ). We'll see more information later 《 thorough JVM—JVM Class execution mechanism 》.

Before , We have also mentioned ,JVM The logical memory model is as follows :

 

  Now let's take a look at what each does one by one !

1、 Program counter

Program counter (Program Counter Register) It's a small amount of memory , Its function can be seen

It is the line number indicator of the bytecode executed by the current thread . In the conceptual model of virtual machines ( Conceptual model only ,

Various virtual machines may be implemented in more efficient ways ), The bytecode interpreter works by changing

The value of this counter is used to select the next bytecode instruction to be executed , Branch 、 loop 、 Jump 、 exception handling 、

Basic functions such as thread recovery rely on this counter .

because Java  The multithreading of virtual machine is realized by switching threads in turn and allocating processor execution time

Of , At any given moment , A processor ( It is a kernel for a multicore processor ) Only execute

Instructions in a thread . therefore , In order to recover to the correct execution position after thread switching , Every thread needs

There is a separate program counter , The counters between threads do not affect each other , Independent storage , We call this kind of inner

The storage area is “ Thread private ” Of memory .

If the thread is executing a Java  Method , This counter records the virtual machine bytes being executed

The address of the code instruction ; If what is being executed is Natvie  Method , The counter value is null (Undefined). this

The memory area is the only one in Java  Nothing is specified in the virtual machine specification OutOfMemoryError  Area of situation .

2、Java  Virtual machine stack

Same as the program counter ,Java  Virtual machine stack (Java Virtual Machine Stacks) It's also thread private ,

It has the same life cycle as a thread . The virtual stack describes Java  Memory model for method execution : Each method is implemented

A stack frame will be created at the same time (Stack Frame ①) Used to store local variables 、 Stack operation 、 dynamic

link 、 Method exit information . Each method is called until the procedure completes , It corresponds to a stack frame in

The process of virtual machine stack from stack to stack .

People often put Java  Memory is divided into heap memory (Heap) And stack memory (Stack), This method is rough

Rough ,Java  The partition of memory area is actually much more complicated than that . The popularity of this division can only explain that most programs

What the staff are most concerned about 、 The two most closely related memory areas to object memory allocation are . Which refers to “ Pile up ” After

The meeting is devoted to , And the “ Stack ” This is the virtual machine stack , Or local changes in the virtual machine stack

Scale section .

The local variometer holds various basic data types known at compile time (boolean、byte、char、short、int、

float、long、double)、 Object reference (reference  type , It's not the same as the object itself , According to different virtual

The machine realizes , It might be a reference pointer to the starting address of the object , It may also point to a handle that represents an object or

Other locations related to this object ) and returnAddress  type ( Points to the address of a bytecode instruction ).

among 64  A length of long  and double  Type of data is occupied 2  The local variable space (Slot), rest

The data type of only takes 1  individual . The memory space required for local variables is allocated during compilation , When entering a

When the method is used , The amount of local variable space that this method needs to allocate in the frame is completely determined , While the method is running

Does not change the size of the local variable table .

stay Java  In the virtual machine specification , Two kinds of anomalies are specified for this region : If the stack depth requested by the thread is large

Depending on the depth allowed by the virtual machine , Will throw out StackOverflowError  abnormal ; If the virtual machine stack can be expanded dynamically

( Most of the current Java  Virtual machines can be dynamically expanded , It's just Java  Fixed length... Is also allowed in the virtual machine specification

Virtual machine stack ), Thrown when the extension cannot request enough memory OutOfMemoryError  abnormal .

3、 Native Method Stack

Native Method Stack (Native Method Stacks) It's very similar to what the virtual machine stack does , Its

The difference is that the virtual machine stack executes for the virtual machine Java  Method ( That's bytecode ) service , The local method stack is

It's used for virtual machines Native  Method service . The language used in the virtual machine specification for methods in the local method stack

said 、 Usage and data structure are not mandatory , So the virtual machine can realize it freely . even to the extent that

Some virtual machines ( for example Sun HotSpot  virtual machine ) Directly combine the local method stack and virtual machine stack into one .

Same as the virtual machine stack , The local method stack area is also thrown StackOverflowError  and OutOfMemoryError

abnormal .

4、Java  Pile up

For most applications ,Java  Pile up (Java Heap) yes Java  The largest amount of memory managed by the virtual machine

A piece of .Java  The heap is an area of memory Shared by all threads , Created when the virtual machine starts . Of this memory area

The only purpose is to store object instances , Almost all object instances allocate memory here . This is in Java  virtual

The description in the pseudo machine specification is : All object instances and arrays are allocated on the heap ①, But as the JIT  compiler

The development of escape analysis technology and the maturity of escape analysis technology , On the stack 、 Scalar substitution ② Optimization techniques will lead to some subtle

The change of , All the objects are distributed on the heap, and it's becoming less and less “ absolute ” 了 .

Java  The heap is the main area managed by the garbage collector , So it's also called “GC  Pile up ”(Garbage

Collected Heap, Fortunately, there is no translation in China “ rubbish dump ”). From the perspective of memory recycling , Because now

Collectors are basically generational collection algorithms , therefore Java  The heap can also be subdivided into : The new and the old ;

More detailed Eden  Space 、From Survivor  Space 、To Survivor  Space etc. . If allocated from memory

From the perspective of , Thread shared Java  Multiple thread private allocation buffers may be partitioned in the heap (Thread Local

Allocation Buffer,TLAB). however , No matter what , It has nothing to do with the storage , No matter which area ,

Objects are still stored , The purpose of further partitioning is to better reclaim memory , Or allocate more quickly

Memory . In this chapter , We only discuss the function of memory area ,Java  Of the above areas in the heap

The details of allocation and recycling will be the subject of the next chapter .

according to Java  The specification of the virtual machine specification ,Java  The heap can be in a physically discontinuous memory space , as long as

Logically continuous , It's like our disk space . At the time of implementation , It can be realized as a fixed size

Of , It can also be extensible , However, the current mainstream virtual machines are implemented according to scalability ( adopt -Xmx

and -Xms  control ). If there is no memory in the heap to complete the instance allocation , And the heap cannot be extended , It will be thrown out.

OutOfMemoryError  abnormal .

4、 Method area

Method area (Method Area) And Java  Pile up , Is an area of memory Shared by each thread , It is used for storage

Store class information that has been loaded by the virtual machine 、 Constant 、 Static variables 、 Real time compiler compiled code and other data . though

however Java  The virtual machine specification describes the method area as a logical part of the heap , But it has an alias called Non-

Heap( Non heap ), The purpose should be with Java  Heap differentiation .

For habits in HotSpot  For developers who develop and deploy programs on virtual machines , Many people are willing to put the method area

be called “ Forever ”(Permanent Generation), They're not essentially equivalent , Just because HotSpot  virtual

The design team of the simulator chose GC  Generational collection extends to the method area , Or using a permanent generation to implement the method area instead of

has . For other virtual machines ( Such as BEA JRockit、IBM J9  etc. ) There is no concept of permanent generation . namely

Make yes HotSpot  Virtual machine itself , According to the official road map , Now, there are also those who give up and live forever “ house-moving ”

to Native Memory  To realize the planning of the method area .

Java  This is a very loose area for virtual machines , Except for and Java  The heap does not need a continuous inner

Save and can choose fixed size or expandable , You can also choose not to implement garbage collection . Relatively speaking , The garbage

Collection behavior is rare in this area , But it is not the data that enters the method area, just like the name of the permanent generation

sample “ permanent ” There is . The memory recycling target in this area is mainly for the recycling of constant pools and the unloading of types

load , In general this area of recycling “ achievement ” More unsatisfactory , In particular, type uninstall , Conditions

Quite demanding , But the recycling of this part of the area is really necessary . stay Sun  The company's BUG  In the list , Zeng Chu

There have been several serious BUG  Because of the lower version HotSpot  The virtual machine is not fully recycled in this area

Cause memory leak .

according to Java  The specification of the virtual machine specification , When the method area cannot meet the memory allocation requirements , Will throw out

OutOfMemoryError  abnormal .

5、 Runtime constant pool

Runtime constant pool (Runtime Constant Pool) Is part of the method area .Class  Except for

Version of class 、 Field 、 Method 、 Interface description and other information , Another piece of information is the constant pool (Constant Pool

Table), Used to store various literal quantities and symbol references generated during compilation , This part will be stored after the class is loaded

To the runtime constant pool of the method area .

Java  Virtual machines are right Class  Each part of the document ( Naturally, constant pools are also included ) There are strict rules for the format of

set , Each byte used to store what kind of data must meet the requirements of the specification , This will be recognized by the virtual machine 、

Load and execute . But for runtime constant pools ,Java  The virtual machine specification does not require any details , Different

The virtual machine implemented by the provider can implement this memory area according to its own needs . however , Generally speaking , except

Saved Class  Outside of the symbol reference described in the file , The translated direct references are also stored in the runtime

In the measuring pool ①.

Runtime constant pool relative to Class  Another important feature of file constant pool is its dynamic nature ,Java  language

The statement does not require that constants must be generated only at compile time , It's not preset Class  The contents of the constant pool in the file

To enter the method area runtime constant pool , It is also possible to pool new constants during runtime , This feature was developed

What people use more is String  Class intern()  Method .

Since the runtime constant pool is part of the method area , The method area memory is naturally limited , When the constant pool has no

When the method applies for memory again, it will throw OutOfMemoryError  abnormal

6、 Direct memory

Direct memory (Direct Memory) It's not part of the virtual machine runtime datazone , Neither Java

Memory area defined in virtual machine specification , But this part of memory is also frequently used , And it can also lead to

OutOfMemoryError  Abnormal appearance , So we're going to talk about it here .

stay JDK 1.4  Newly added NIO(New Input/Output) class , A channel based approach is introduced (Channel)

With the buffer (Buffer) Of I/O  The way , It can be used Native  Function library directly allocates out of heap memory , however

After a storage in Java  In the pile DirectByteBuffer  Object as a reference to this memory

operation . This can significantly improve performance in some scenarios , Because it avoids Java  Heaps and Native  From the pile

Copy data back .

obviously , The allocation of local direct memory will not be affected Java  Heap size limits , however , Since it's memory , be

I'm sure it will still receive the total memory of this machine ( Include RAM  And SWAP  Area or paging file ) Size and processor

Addressing space limitations . When the server administrator configures the virtual machine parameters , Generally, it will be set according to the actual memory -Xmx

Isoparametric information , But direct memory is often ignored , Make the sum of each memory area greater than the physical memory limit

( Including physical and operating system level limitations ), This leads to the emergence of dynamic expansion OutOfMemoryError

abnormal .

The logical memory model we've seen , How do we access an object when we create it ?

stay Java  In language , How object access works ? Object access in Java  Language is everywhere , It's the most common procedural behavior , But even the simplest access , It will also involve Java  Stack 、Java  Pile up 、 Method area these three most important memory areas

Association between domains , As the code below :

Object obj = new Object();

Suppose the code appears in the method body , that “Object obj” The semantics of this part will reflect Java  Stack

In the local variable table of , As a reference  Type data appears . and “new Object()” The semantics of this part

It will reflect Java  In the pile , Form a piece of storage Object  Type all instance data values (Instance Data, Yes

Data of each instance field in the image ) Of structured memory , According to the specific type and the object memory layout implemented by the virtual machine

game (Object Memory Layout) Different , The length of this memory is not fixed . in addition , stay Java  In the pile

It must also contain data that can be found for this object type ( Such as object type 、 Parent class 、 Implemented interface 、 Such method ) Land

Address information , These types of data are stored in the method area .

because reference  Type in the Java  The virtual machine specification only specifies a reference to an object , did not

Define how this reference should be located , And visit Java  The specific location of the objects in the heap , therefore

Different virtual machines implement different object access methods , There are two main ways of visiting : Use handles and direct

The pointer .

If you use handle access ,Java  A block of memory will be divided in the heap as a pool of handles ,reference

Is the handle address of the object , The handle contains the object instance data and the type data

Specific address information , As shown in the figure below .

 

  If you use direct pointer access ,

Java  In the layout of heap objects, we must consider how to put access types

Information about data ,reference  The object address is directly stored in the , As shown in the figure below

 

  These two ways of accessing objects have their own advantages , The biggest benefit of using handle access is

reference  Zhongcun

Store a stable handle address , When the object is moved ( Moving objects during garbage collection is a very common behavior ) Time only

Will change the instance data pointer in the handle , and reference  It doesn't need to be modified .

The biggest benefit of using direct pointer access is that it's faster , It saves a pointer positioning time

pin , Because the access of the object Java  Very often , Therefore, this kind of expense is also a very considerable after a small amount adds up

Execution cost . Main virtual machines discussed in this book Sun HotSpot  for , It uses the second way to access objects , But from the perspective of the whole scope of software development , It is also common for languages and frameworks to use handles for access .

Let's take a look at a few examples

1、Java  Heap overflow

In the following procedure, we limit Java  The heap size is 20MB, Non scalable ( The minimum value of the heap -Xms  ginseng

Number and maximum -Xmx  Set the parameter to the same to avoid automatic heap expansion ), Through parameters -XX:+HeapDump

OnOutOfMemoryError  Can let virtual machine in the event of memory overflow exception Dump  Get the current memory heap dump

Snapshots for later analysis .

The parameters are set as follows

 

package com.yhj.jvm.memory.heap;

import java.util.ArrayList;

import java.util.List;

/**

 * @Described: Heap overflow test

 * @VM args:-verbose:gc -Xms20M -Xmx20M -XX:+PrintGCDetails

 * @author YHJ create at 2011-11-12 Afternoon 07:52:22

 * @FileNmae com.yhj.jvm.memory.heap.HeapOutOfMemory.java

 */

public class HeapOutOfMemory {

    /**

     * @param args

     * @Author YHJ create at 2011-11-12 Afternoon 07:52:18

     */

    public static void main(String[] args) {

       List<TestCase> cases = new ArrayList<TestCase>();

       while(true){

           cases.add(new TestCase());

       }

    }

}

/**

 * @Described: The test case

 * @author YHJ create at 2011-11-12 Afternoon 07:55:50

 * @FileNmae com.yhj.jvm.memory.heap.HeapOutOfMemory.java

 */

class TestCase{

   

}

Java  Heap memory OutOfMemoryError Exception is the most common memory overflow exception in practical application . appear Java  In pile

When the storage overflows , Exception stack information “java.lang.OutOfMemoryError” I'll follow you further “Java heap

space”.

To resolve exceptions in this area , The general method is to use the memory image analysis tool first ( Such as Eclipse

Memory Analyzer) Yes dump  Analysis of the heap dump snapshot , The point is to make sure that the objects in memory are

No is necessary , That is to say, we need to be clear about the memory leak (Memory Leak) Or memory overflow

Out (Memory Overflow). chart 2-5  Shows the use of Eclipse Memory Analyzer  Open heap dump fast

According to the document .

If it's a memory leak , You can further view the leaked objects to GC Roots  Reference chain of . So he

We can find the path through which the leaking object is connected to GC Roots  Associated and causes the garbage collector to fail to recycle automatically

Their . Master the type information of the leaking object , as well as GC Roots  Reference chain information , Can be more accurate

Locate the location of the leaked code .

If there is no leakage , In other words, all objects in memory must be alive , Then you should check

Heap parameters of the virtual machine (-Xmx  And -Xms), Compare with the physical memory of the machine to see if it can be increased , From the code

Check if there are some objects whose life cycle is too long 、 Long holding time , Try to reduce program run time

Memory consumption of .

The above is the treatment Java  A brief idea of heap memory problem , The knowledge needed to deal with these problems 、 Tools and experience

In the next few sharing sessions, I will do some additional analysis .

2、java Stack overflow

package com.yhj.jvm.memory.stack;

/**

 * @Described: Probe into the lack of stack level

 * @VM args:-Xss128k

 * @author YHJ create at 2011-11-12 Afternoon 08:19:28

 * @FileNmae com.yhj.jvm.memory.stack.StackOverFlow.java

 */

public class StackOverFlow {

   

   

    private int i ;

   

    public void plus() {

       i++;

       plus();

    }

    /**

     * @param args

     * @Author YHJ create at 2011-11-12 Afternoon 08:19:21

     */

    public static void main(String[] args) {

       StackOverFlow stackOverFlow = new StackOverFlow();

       try {

           stackOverFlow.plus();

       } catch (Exception e) {

           System.out.println("Exception:stack length:"+stackOverFlow.i);

           e.printStackTrace();

       } catch (Error e) {

           System.out.println("Error:stack length:"+stackOverFlow.i);

           e.printStackTrace();

       }

    }

}

3、 Constant pool overflow ( What information does the constant pool have , We are following up JVM Class file structure )

package com.yhj.jvm.memory.constant;

import java.util.ArrayList;

import java.util.List;

/**

 * @Described: Constant pool memory overflow exploration

 * @VM args : -XX:PermSize=10M -XX:MaxPermSize=10M

 * @author YHJ create at 2011-10-30 Afternoon 04:28:30

 * @FileNmae com.yhj.jvm.memory.constant.ConstantOutOfMemory.java

 */

public class ConstantOutOfMemory {

    /**

     * @param args

     * @throws Exception

     * @Author YHJ create at 2011-10-30 Afternoon 04:28:25

     */

    public static void main(String[] args) throws Exception {

       try {

           List<String> strings = new ArrayList<String>();

           int i = 0;

           while(true){

              strings.add(String.valueOf(i++).intern());

           }

       } catch (Exception e) {

           e.printStackTrace();

           throw e;

       }

    }

}

4、 Method to overflow

package com.yhj.jvm.memory.methodArea;

import java.lang.reflect.Method;

import net.sf.cglib.proxy.Enhancer;

import net.sf.cglib.proxy.MethodInterceptor;

import net.sf.cglib.proxy.MethodProxy;

/**

 * @Described: Method area overflow test

 * Using technology CBlib

 * @VM args : -XX:PermSize=10M -XX:MaxPermSize=10M

 * @author YHJ create at 2011-11-12 Afternoon 08:47:55

 * @FileNmae com.yhj.jvm.memory.methodArea.MethodAreaOutOfMemory.java

 */

public class MethodAreaOutOfMemory {

    /**

     * @param args

     * @Author YHJ create at 2011-11-12 Afternoon 08:47:51

     */

    public static void main(String[] args) {

       while(true){

           Enhancer enhancer = new Enhancer();

           enhancer.setSuperclass(TestCase.class);

           enhancer.setUseCache(false);

           enhancer.setCallback(new MethodInterceptor() {

              @Override

              public Object intercept(Object arg0, Method arg1, Object[] arg2,

                     MethodProxy arg3) throws Throwable {

                  return arg3.invokeSuper(arg0, arg2);

              }

           });

           enhancer.create();

       }

    }

}

/**

 * @Described: The test case

 * @author YHJ create at 2011-11-12 Afternoon 08:53:09

 * @FileNmae com.yhj.jvm.memory.methodArea.MethodAreaOutOfMemory.java

 */

class TestCase{

   

}

5、 Direct memory overflow

package com.yhj.jvm.memory.directoryMemory;

import java.lang.reflect.Field;

import sun.misc.Unsafe;

/**

 * @Described: Direct memory overflow test

 * @VM args: -Xmx20M -XX:MaxDirectMemorySize=10M

 * @author YHJ create at 2011-11-12 Afternoon 09:06:10

 * @FileNmae com.yhj.jvm.memory.directoryMemory.DirectoryMemoryOutOfmemory.java

 */

public class DirectoryMemoryOutOfmemory {

    private static final int ONE_MB = 1024*1024;

    private static int count = 1;

    /**

     * @param args

     * @Author YHJ create at 2011-11-12 Afternoon 09:05:54

     */

    public static void main(String[] args) {

       try {

           Field field = Unsafe.class.getDeclaredField("theUnsafe");

           field.setAccessible(true);

           Unsafe unsafe = (Unsafe) field.get(null);

           while (true) {

              unsafe.allocateMemory(ONE_MB);

              count++;

           }

       } catch (Exception e) {

           System.out.println("Exception:instance created "+count);

           e.printStackTrace();

       } catch (Error e) {

           System.out.println("Error:instance created "+count);

           e.printStackTrace();

       }

    }

}

原网站

版权声明
本文为[Southern kingdom_ Love]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/02/202202200545328917.html