1、JVM由字节码执行引擎、类装载子系统、运行时数据区组成。c++
1.类装载子系统主要是把class文件加载到运行时数据区中,算法
2.字节码执行引擎主要是执行字节码文件,并把执行的相应的行数数据推送到运行时数据区中的程序计数器中jvm
3.运行时数据区是文件执行的主要场所。spa
2、运行时数据区由下面几个区域构成:线程
1.堆:大多数对象建立以后都放在堆中,少数放在栈中指针
2.栈:每一个线程产生都会有一个独有的线程栈(在栈上分的一小块内存),栈的主要做用是为程序运行提供场所,即程序的执行操做在栈中进行对象
3.本地方法栈:存放一些执行本地方法的地址指针,主要是一些早期的c++执行的本地方法blog
4.程序计数器:记录程序运行的位置,若是被打断以后能够接着打断的地方接着运行内存
5.方法区(元空间):存放一些静态变量、类元信息等字符串
元空间和堆是全部执行文件所共享的区域,即一个静态变量被建立以后能够被另外一个线程所引用
而每个线程都有本身的其余区域,即线程栈、程序计数器和本地方法栈,线程结束后即被销毁
3、分别介绍:
1.堆(垃圾回收机制):堆分为年轻代和老年代,空间大小为1:2,年轻代又分为eden区和survivor区,比例为8:1:1,以上两个比例皆能够修改
对象在被建立后放入Eden区中,当Eden区放满以后,会进行一次minor gc,经过可达性算法分析,将垃圾对象进行回收,而后将不是垃圾的对象放入survivor1区中,通过程序执行以后,若是eden区再次放满,则会将Eden区和survivor1区中的对象进行垃圾回收,将仍然存活的对象放入survivor2区中,即每次进行垃圾回收后的对象都放在另外一个survivor区中,直到对象的分带年龄达到设定值以后(默认为15,由于对象中的分代年龄指针占四个字节,最大值为15),放入老年代,其中,对象每经历一次minor gc,分代年龄就会加一。老年代通过屡次minor gc后,也会放满,若是老年代放满,程序会进行full gc,即,程序会进行STW(stop the ),即终止程序运行,而后经过可达性分析算法,进行一次full gc。若是对象仍然存活,则继续存放在老年代中,若是老年代的对象full gc以后仍然满了,则会出现内存溢出的错误状况。
2.栈:
栈是程序运行的主要场所,每有一个线程运行时,jvm就会给这个线程在栈上分配一块独立的区域(线程栈)去存放本身的局部变量,线程栈的主要由栈帧组成,每一个方法都有一个独立的栈帧,栈帧上主要有:方法出口、动态连接、操做数栈、局部变量表组成。好比执行main方法,则main方法有本身独立的栈和本地方法栈以及程序计数器,根据程序计数器,来进行记录执行的位置,经过字节码执行引擎进行执行,执行main方法时,会给main方法生成一个独立的栈帧,栈帧中本地变量区域放入方法中生成的局部变量,对局部变量进行操做时,将局部变量放入操做数栈中(局部变量作操做时用来中转存放的内存空间),当执行操做时,将操做数栈中的数据顺序出栈,放入外部寄存器中,用运算器进行运算,运算出来结果以后再把值放入操做数栈中,再进行赋值给本地变量。动态连接:程序在加载时,在解析阶段只会进行静态连接(将符号引用替换为直接引用,该阶段会把一些静态方法(符号引用,好比main()方法)替换为指向数据所存内存的指针或句柄等(直接引用),这是所谓的静态连接过程(类加载期间完成),动态连接是在程序运行期间完成的将符号引用替换为直接引用,下节课会讲到动态连接),即只解析静态方法,当程序运行到静态方法中的普通方法时,会进行动态连接。由于程序在加载阶段会把编译为一条条指令文件,而后存放在元空间的常量池中,因此在执行动态连接时,即是找到该方法的在元空间常量池的地址。方法出口:一个方法运行完成以后返回到上层调用方法的哪个位置。若是方法中引用对象信息,则对应点局部变量表中保存的是堆中对象的地址指针。
3.程序计数器:
记录程序运行的位置,若是程序暂停,再从新开始后,程序会从程序计数器的位置开始执行,程序计数器的位置是外部字节码执行引擎执行发送的地址。
4.本地方法栈:
存放一些本地底层的方法。
5.方法区(元空间):
存放静态变量、字符串常量池、对象常量池、类元信息等。静态变量:文件在加载过程当中,在准备阶段对一些静态变量进行分配空间,并赋予默认值,在初始化阶段再进行赋初始值。常量池:存放相应信息。类元信息:文件在加载过程当中,在加载阶段,文件会编译为字节码文件,其中,相应的类中的方法、变量等相应的信息为类元信息。静态变量是对象类型,则存放指向该对象在堆中的地址。
4、相互之间的联系:
经过类装载子系统进行装载类,而后经过字节码执行引擎进行执行,执行main()方法时,在栈中划分一小部分空间生成线程栈,在线程栈中为main方法生成独立栈帧,若是类中有其余方法,则生成一个新的栈帧,在栈帧中的局部变量表中存放执行过程当中的局部变量,在操做数栈中进行对操做数进栈以及出栈,而后在外部执行运算,在赋值给本地变量,其中执行步骤都是由该线程独有的程序计数器计数执行位置供字节码执行引擎执行。若是栈帧中局部变量为对象类型,则局部变量表中存放的是堆中对象的指针地址。该对象头中存在指针,指向其所属的类,也就是指向方法区中该类的地址。当一个类加载到jvm中会产生类对象,即在堆中存放的class对象,方法区中的类元信息会再次指向堆中的class类对象。
若是方法区(元空间)中静态变量是对象类型,则方法区(元空间)的常量池中存放指向该对象在堆中的地址。