1.JVM组成部分:
栈,本地方法栈,程序计数器,堆,方法区(元空间)。其中堆和方法区线程共享数据,而其他三个线程私有数据。
2.JVM运行过程:
一个Java的class类通过类加载子系统进入JVM,将其代码由上至下进行压栈操作,通过先进后出来保证执行顺序一致。每运行一行代码,程序计数器加1。其非java语言的代码放入本地方法区。其运行过程中生成的类对象或数组,集合等对象放进堆中,通过先进先出来保证对象的正确性。其加载的类信息,常量,静态变量放入方法区保存。
3.栈运行过程:
main方法中有变量a等于add方法返回值,add的方法里写的是变量a=1,b=1,c=a+b,再返回c
这行代码在栈中的运行过程如下:
(1). 先将main方法进行压栈形成一个main栈帧,再将add方法也进行压栈形成add栈帧。
(2).将add方法中的变量a压入add栈帧的局部变量表中,数值1压入add栈帧的操作数栈中,等号赋值时将数值1出栈写进变量a指向的地址中。变量b类似变量a的操作。
(3).变量c时将其变量c压入add栈帧的局部变量表中,再从变量a和变量b取到数值1和数值2压栈进入add栈帧的操作数栈中,做加法运算符时将数值1和数值2出栈算出数值3,再将数值3压栈进入add栈帧的操作数栈中,等于赋值时数值3出栈写进变量c指向地址。
(4). 返回c是通过add栈帧的方法出口找到main栈帧的的局部变量表中的变量a,再将其数值3写进对应的地址中。
如果变量赋值的不是基本类型,而是对象时,变量还是放在栈帧的局部变量表中,但是对象就放在堆中,将其变量指向堆中的对象。
4.程序计数器:指向当前线程所执行的字节码指令的(地址)行号.
5.本地方法栈:添加native关键字修饰的方法放进其中,一般是用来执行C,C++等其他语言的代码。
6.方法区(元空间):类的模板属性如常量,成员变量等类信息。
7.堆的组成部分:分为新生代和老年代,比例一般为1:2。其中新生代中一般有伊甸园区和S1和S2,比例一般为8:1:1。对象一般是在伊甸园中产生,也有特殊对象直接进入老年代。
8.堆的回收机制:
(1).minor gc:当伊甸园区的内存被对象占满时触发,通过对象引用数是不是为0来判断游离状态,如果是清除该对象,不是将其放入S1中。从而将伊甸园区请空。每次伊甸园区的minor gc触发时,S1中的对象引用数为0时也会清除,不为0时这个对象的存在次数会加1。如果存在次数大于15时,会将这个对象存入老年代的内存中。当运行到S1的内存被占满时,将其所有对象拷贝进S2并存在次数加1,本身内存中的对象全部清空。然后minor gc触发时,将其引用数不为0的对象放进S2,S2内存满后将其所有对象拷贝进S1,使S1和S2的内存来回利用。
(2).full gc:当老年代的内存被占满时会报内存溢出的错误导致程序服务失败。