1、JVM总体内容体系
2、什么是JVM
定义
一种能够运行java字节码的虚拟机。java字节码是已经经过编译,但与特定机器码无关,需要解释器转译后才能成为机器码的中间码。
为什么要JVM
首先我们先来看下一个java文件是怎么被翻译成机器语言的。
编写—>.java文件----->进行编译(javac)------>得到.class字节码文件----->解释(JVM)------>机器语言
JVM是Java跨平台运行的基础,如果没有JVM,我们编写的Java程序实现同一个功能想要在不同的操作系统上运行,则我们得编写N多套分别能够在不同操作系统上执行的程序代码。
JVM有不同的版本,可用来支持不同的操作系统和机器。编译器将.java文件翻译为.class文件,.class文件是通用的。不同的JVM再将.class文件解释成不同的机器语言。
JVM体系结构
执行流程
.class文件被Class loader类加载器加载进运行时数据区,然后又执行引擎执行这些字节码,如果需要与异构系统交互,可以通过本地接口进行。
每个线程被创建后,会产生一个对应的程序计数器和栈帧,程序计数器用于记录下一条将要执行的指令,Java栈中存放的是栈帧,每个方法从调用到执行完毕都对应栈帧在Java栈中的入栈和出栈。
各类组件解释
(1)Class Loader:类加载器
类加载器读取.class文件,将其转换成java.lang.Class类的一个实例,每个实例用来表示一个java类,通过该实例的newInstance()方法可以创建出一个该类的对象。
这一块和反射联系密切。
(2)Execution Engine:执行引擎*
用来执行字节码或本地方法。
(3)Native Interface:本地接口
它允许java代码与其它语言(比如C、C++)编写的应用程序和库进行交互。
(4)Runtime Data Area:运行数据区
• 方法区:
其中包含的都是在整个程序中永远唯一的元素,比如class,static变量。
• 堆:
堆是用来存储对象实例以及数组值的区域。java中所有通过new创建的对象的内存都在此分配。堆中的对象的内存需要等待GC进行回收。
• java栈:
栈中只保存基础数据类型(java的8种基本数据类型)和非基本类型的对象的指向堆的地址的引用。
• 本地方法栈:
如果某个虚拟机实现的本地方法接口是使用C连接模型的话,那么它的本地方法栈就是C栈。
• 程序计数器:
用于存储每个线程下一步将执行的JVM指令,如果该方法为native,则其内部不存储任何信息。
Java堆分代介绍
堆就是用于类的诞生、成长、消亡的区域。一个类在这里产生,应用,最后被垃圾回收器收集,结束生命。堆分为3代:新生代、老年代、永久代。
新生代又分为伊甸区(Eden Space)、幸存区0(Survivor 0 Space)、幸存区1(Survivor 1 Space)
当幸存区的对象不再被引用的时候,GC这时候就起作用了,GC会把新生代的不再被引用的对象进行销毁回收,然后剩余的没有被回收的对象将被放到下一代,依次类推
当老年代(也就是养老区)也满了是,这时会抛出内存溢出异常
注意:JDK8中将永久代区改成了元空间