JVM memory division (transfer)

JVM memory area division

 

To learn Java, it is inevitable to learn the Java virtual machine, that is, the JVM. The Java virtual machine specification specifies the runtime data area that will be used during program execution. This is also the model of the JVM's memory area division, so it should be understandable.

Some of them are created and destroyed with the startup and exit of the virtual machine. These areas are shared by threads, and some are bound to each thread. They are created and destroyed with the start and end of threads. We These areas can be said to be thread private.

According to the "Java Virtual Machine Specification Java SE 7 Edition" and "Java Virtual Machine Specification Java SE 8 Edition", we can divide the following runtime data areas, as shown in the following figure:

Java heap

In the Java virtual machine, the heap is a runtime memory area that can be shared by various threads, and is also an area where all class instances and array objects allocate memory. This area is created with the startup of the virtual machine. Its only mission is to store object instances . This area is also the main focus of GC.

The following is the division of the JVM heap on my notebook. You can see that it is divided into the new generation, the old generation and the permanent generation. The new generation can be divided into Eden Space, From Survivor Space and To Survivor Space.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
Heap Usage:
PS Young Generation
Eden Space:
   capacity = 17301504 (16.5MB)
   used     = 2483088 (2.3680572509765625MB)
   free     = 14818416 (14.131942749023438MB)
   14.351862127130682% used
From Space:
   capacity = 2621440 (2.5MB)
   used     = 2615312 (2.4941558837890625MB)
   free     = 6128 (0.0058441162109375MB)
   99.7662353515625% used
To Space:
   capacity = 6291456 (6.0MB)
   used     = 0 (0.0MB)
   free     = 6291456 (6.0MB)
   0.0% used
PS Old Generation
   capacity = 44564480 (42.5MB)
   used     = 13316368 (12.699478149414062MB)
   free     = 31248112 (29.800521850585938MB)
   29.88112505744485% used
PS Perm Generation
   capacity = 22020096 (21.0MB)
   used     = 14907008 (14.2164306640625MB)
   free     = 7113088 (6.7835693359375MB)
   67.6972888764881% used

 

根据虚拟机规范的规定,Java堆可以是固定的大小也可以是按照需求动态扩展的,而且不需要保证是连续的。

存放内容:所有的对象实例和数组。

方法区

方法区是一个线程共享的区域,它用于存储已被虚拟机加载的类信息、常量、静态变量。方法区是堆的逻辑组成部分,Hotspot用永久代实现了方法区。
方法区还包含运行时常量池,用于存放编译时生成的各种字面量和符号引用,但是不要求常量一定是在编译时期产生的,运行期间也可以将新的常量放入池中,比如String的intern()方法便是利用了这一特性。

存放内容:类的结构信息,如类的字段、方法、接口、构造函数,还有运行时常量池等。

程序计数寄存器

这块区域是每个线程独立拥有的,也就是线程私有的,我们可以把它看作是当前线程所执行的字节码的行号指示器。

这块区域时虚拟机规范里面唯一一个没有规定任何OutOfMemoryError情况的区域。

存放内容:如果线程执行的是一个Java方法,那么寄存器里面记录的就是正在执行的虚拟机字节码指令的地址,如果线程执行的是一个native方法,那么寄存器记录的值为undefined。

虚拟机栈

虚拟机栈也是线程私有的内存区域。每个方法在执行的时候都会创建一个栈帧用于存储局部变量表、操作数栈、方法出口等信息,每一个方法从调用到执行完成就是一个栈帧入栈和出栈的过程。

局部变量表存放了编译时期可知的各种基本数据类型、对象引用和指向了一条字节码指令的地址。

存放内容:局部变量表、操作数栈、方法出口等信息。

本地方法栈

和虚拟机栈类似,存储Native方法的相关信息。
存放内容:局部变量表、操作数栈、方法出口等信息。

Guess you like

Origin http://10.200.1.11:23101/article/api/json?id=326565994&siteId=291194637