Skip to content

Commit be794d2

Browse files
committed
JVM内存结构优化
1 parent a089a11 commit be794d2

File tree

4 files changed

+15
-13
lines changed

4 files changed

+15
-13
lines changed

MD/Java基础-JVM原理.md

Lines changed: 15 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,32 @@
1-
21
## JVM原理
3-
JVM本身是介于JAVA编译器和操作系统之间的程序,这个程序提供了一个无视操作系统和硬件平台的运行环境
4-
52
### Java内存区域的分配
6-
以1.8为例,内存区域如下:
3+
JVM虚拟机内存模型实现规范:
4+
5+
![](https://github.com/xbox1994/2018-Java-Interview/raw/master/images/JVM规范.png)
76

8-
![](https://github.com/xbox1994/2018-Java-Interview/raw/master/images/j1.jpg)
97

108
按线程是否共享分为以下区域:
119

1210
所有线程共享的数据区:
1311

14-
1. 方法区(JVM规范中的一部分,并不是实际的实现): 存储已被虚拟机加载的类信息、方法信息、常量、静态变量、字节码、JIT编译后的本地代码,并使用永久代来实现方法区。1.8中用元空间替代了永久代,元空间并不在虚拟机中,而是使用本地内存,元空间中存在JIT即时编译后的native代码,可能还存在短指针数据区CCS
15-
2. 堆区: 最大的一块区域,用于存放对象的区域,1.7之后常量池移到这里
12+
1. 方法区(JVM规范中的一部分,不是实际的实现): 存储每一个类的结构信息(运行时常量池、静态变量、方法数据、构造函数和普通方法的字节码、JIT编译后的代码),没有要求使用垃圾回收因为回收效率太低
13+
2. 堆区: 最大的一块区域,是大部分类实例、对象、数组分配内存的区域,没有限制只能将对象分配在堆,所以出现逃逸分析的技术
1614

1715
每个线程都会有一块私有的数据区:
1816

19-
1. 虚拟机栈: 每个方法执行时在其中创建一个栈帧,用于存储局部变量、操作数栈、动态链接、方法出口等信息
17+
1. 虚拟机栈: 虚拟机栈与线程同时创建,每个方法在执行时在其中创建一个栈帧,用于存储局部变量、操作数栈、动态链接、方法返回地址。正常调用完成后恢复调用者的局部变量表、操作数栈、递增程序计数器来跳过刚才执行的指令,或抛出异常不将返回值返回给调用者
2018
2. 本地方法栈: 功能与虚拟机栈相同,为native方法服务
21-
3. 程序计数器: 存放当前正在执行的指令的地址
19+
3. pc寄存器: 任意时刻线程只会执行一个方法的代码,如果不是native的,就存放当前正在执行的字节码指令的地址,如果是native,则是undefined
20+
21+
以HotSpot虚拟机实现为例,Java8中内存区域如下:
22+
23+
![](https://github.com/xbox1994/2018-Java-Interview/raw/master/images/JVM1.8.png)
2224

23-
直接内存
25+
与规范中的区别
2426

25-
* 直接内存并非Java标准
26-
* JDK1.4 加入了新的 NIO 机制,目的是防止 Java 堆 和 Native 堆之间往复的数据复制带来的性能损耗,此后 NIO 可以使用 Native 的方式直接在 Native 堆分配内存。
27-
* 直接内存区域是全局共享的内存区域。
27+
1. 直接内存:非Java标准,是JVM以外的本地内存,在Java4出现的NIO中,为了防止Java堆和Native堆之间往复的数据复制带来的性能损耗,此后NIO可以使用Native的方式直接在Native堆分配内存。JDK中有一种基于通道(Channel)和缓冲区(Buffer)的内存分配方式,将由C语言实现的native函数库分配在直接内存中,用存储在JVM堆中的DirectByteBuffer来引用
28+
2. 元数据区(方法区的实现):Java7以及之前是使用的永久代来实现方法区,大小是在启动时固定的,GC。Java8中用元空间替代了永久代,元空间并不在虚拟机中,而是使用本地内存,但是也能进行GC。元空间存储JIT即时编译后的native代码,可能还存在短指针数据区CCS
29+
3. 堆区: Java7之后运行时常量池从方法区移到这里,为Java8移除永久带的做好准备
2830

2931
### Java对象不都是分配在堆上
3032
还能分配在栈上

images/JVM1.8.png

43.5 KB
Loading

images/JVM规范.png

32.7 KB
Loading

images/j1.jpg

-56 KB
Binary file not shown.

0 commit comments

Comments
 (0)