文章目录
- 概要
- JVM 是 Java程序的运行环境(java二进制字节码的运行环境)
- JVM 的主要组成部分
- 运行流程:
- 程序计数器
- 堆
- 元空间
- 方法区
- 常量池
- 运行时常量池
概要
JVM 是 Java程序的运行环境(java二进制字节码的运行环境)
好处:
1.一次编写,到处运行
2.自动内存管理,垃圾回收机制
JVM 的主要组成部分
ClassLoader(类加载器)
Runtime Data Area(运行时数据区,内存分区)
Execution Engine(执行引擎)
Native Method Library(本地库接口)
运行流程:
(1)类加载器(ClassLoader)把Java代码转换为字节码
(2)运行时数据区(Runtime Data Area)把字节码加载到内存中,而字节码文
件只是JVM的一套指令集规范,并不能直接交给底层系统去执行,而是有执行引
擎运行
(3)执行引擎(Execution Engine)将字节码翻译为底层系统指令,再交由CPU
执行去执行,此时需要调用其他语言的本地库接口(Native Method Library)来
实现整个程序的功能。
程序计数器
程序计数器:线程私有的,内部保存的字节码的行号。用于记录正在执行的字节
码指令的地址。
javap -verbose xx.class 打印堆栈大小,局部变量的数量和方法的参数。
程序计数器是JVM规范中唯一一个没有规定出现OOM的区域,所以这个空间也
不会进行GC
堆
线程共享的区域:主要用来保存对象实例,数组等,当堆中没有内存空间可分配
给实例,也无法再扩展时,则抛出OutOfMemoryError异常。
- 年轻代被划分为三部分,Eden区和两个大小严格相同的Survivor区,根据JVM
的策略,在经过几次垃圾收集后,任然存活于Survivor的对象将被移动到老年
代区间。 - 老年代主要保存生命周期长的对象,一般是一些老的对象
- 元空间保存的类信息、静态变量、常量、编译后的代码
为了避免方法区出现OOM,所以在java8中将堆上的方法区【永久代】给移动到
了本地内存上,重新开辟了一块空间,叫做元空间。那么现在就可以避免掉
OOM的出现了
元空间
在 HotSpot JVM 中,永久代( ≈ 方法区)中用于存放类和方法的元数据以及常
量池,比如Class 和 Method。每当一个类初次被加载的时候,它的元数据都会放
到永久代中。
元空间的本质和永久代类似,都是对 JVM 规范中方法区的实现。不过元空间与
永久代之间最大的区别在于:元空间并不在虚拟机中,而是使用本地内存。因
此,默认情况下,元空间的大小仅受本地内存限制。
方法区
- 方法区(Method Area)是各个线程共享的内存区域
- 主要存储类的信息、运行时常量池
- 虚拟机启动的时候创建,关闭虚拟机时释放
常量池
查看字节码结构(类的基本信息、常量池、方法定义) javap -v xx.class
运行时常量池
常量池是 *.class 文件中的,当该类被加载,它的常量池信息就会放入运行时常量
池,并把里面的符号地址变为真实地址