图示JVM事情道理
Centos7.X 搭建Prometheus+node_exporter+Grafana实时监控平台
JDK,JRE,JVM的联络是啥?
JVM Java Virtual Machine
JDK Java Development Kit
JRE Java Runtime Environment
看上图官方的引见讲的很清晰
JVM的作用是啥?
JVM有2个迥殊有意思的特征,言语无关性和平台无关性。
言语无关性是指完成了Java虚拟机范例的言语对能够在JVM上运转,如Groovy,和在大数据范畴比较火的言语Scala,由于JVM终究运转的是class文件,只需终究的class文件复合范例就能够在JVM上运转。
平台无关性是指安装在差别平台的JVM会把class文件解释为当地的机械指令,从而完成Write Once,Run Anywhere
JVM运转时数据区
Java虚拟机在实行Java程序的历程当中会把它所治理的内存划分为若干个差别的数据地区。这些地区都有各自的用处,以及建立和烧毁的时刻,有的地区跟着虚拟机历程的启动而存在,有些地区则依靠用户线程的启动和完毕而竖立和烧毁。Java虚拟机所治理的内存将会包含以下几个运转时数据地区
个中要领区和堆是一切线程同享的数据区
程序计数器,虚拟机栈,当地要领栈是线程断绝的数据区,画一个逻辑图
程序计数器
程序计数器是一块较小的内存空间,它能够看做是当前线程所实行的字节码的行号指示器
为何要纪录当前线程所实行的字节码的行号?直接实行完不就能够了吗?
由于代码是在线程中运转的,线程有大概被挂起。即CPU一会实行线程A,线程A还没有实行完被挂起了,接着实行线程B,末了又来实行线程A了,CPU得晓得实行线程A的哪一部份指令,线程计数器会通知CPU。
虚拟机栈
虚拟机栈存储当前线程运转要领所须要的数据,指令,返回地点。虚拟机栈形貌的是Java要领实行的内存模子:每一个要领在实行的同时都邑建立一个栈帧用于存储局部变量表,操作数栈,动态链接,要领出口等信息。每一个要领从挪用直至实行完成的历程,就对应着一个栈帧在虚拟机栈中从入栈道出栈的历程。
局部变量表存储存储局部变量,是一个定长为32位的局部变量空间。个中64位长度的long和double范例的数据会占用2个局部变量空间(Slot),其他的数据范例只占用一个。援用范例(new出来的对象)怎样存储?看下图
public int methodOne(int a, int b) {
Object obj = new Object();
return a + b;
}
如果局部变量是Java的8种基础基础数据范例,则存在局部变量表中,如果是援用范例。如String,局部变量表中存的是援用,而实例在堆中。
如果methodOne要领挪用methodTwo要领时, 虚拟机栈的状况以下
当虚拟机栈没法再放下栈帧的时刻,就会涌现StackOverflowError,演示一下
public class JavaVMStackSOF {
private int stackLength = 1;
public void stackLeak() {
stackLength++;
stackLeak();
}
public static void main(String[] args) throws Throwable {
JavaVMStackSOF oom = new JavaVMStackSOF();
try {
oom.stackLeak();
} catch (Throwable e) {
System.out.println("stack length: " + oom.stackLength);
throw e;
}
}
}
在idea中设置运转时的线程的客栈大小为以下
-Xss 参数的作用是设置每一个线程的客栈大小
运转输出为
-Xss参数的值越大,打印输出的深度越大
接着解释一下操作数栈,照样比较轻易明白的
如果Test.java中有以下要领,
public int getSum(int a, int b) {
return a + b;
}
反编译生成的Test.class文件,并输出到show.txt中
javap -v Test.class > show.txt
show.txt的内容以下
public int getSum(int, int);
descriptor: (II)I
flags: ACC_PUBLIC
Code:
stack=2, locals=3, args_size=3
0: iload_1
1: iload_2
2: iadd
3: ireturn
LineNumberTable:
line 12: 0
解释一下上面的语句
iload_1:局部变量1压栈
iload_2:局部变量2压栈
iadd:栈顶2个元素相加,计算结果压栈
简朴2个数相加都邑用到栈,这个栈就是操作数栈,更不用说庞杂的语法了
当地要领栈
当地要领栈(Native Method Stack)与虚拟机栈锁发挥的作用是异常类似的,他们之间的区分不过是虚拟机栈为虚拟机实行Java要领(也就是字节码)效劳,而当地要领栈则为虚拟机使用到的Native要领效劳。
Java堆
关于大多数运用来讲,Java堆(Java Heap)是Java虚拟机锁治理的内存中最大的一块。Java堆是一切线程同享的一块内存地区,在虚拟机启动时建立。此内存地区的唯一目标就是寄存对象实例,险些一切的对象实例都在这里分派内存
要领区
要领区(Method Area)与Java堆一样,是各个线程同享的内存地区,它用于存储已被虚拟机加载的类信息,常量,静态变量,立即编译器编译后的代码等数据。
JVM内存模子
由色彩能够看出,jdk1.8之前,堆内存被分为新生代,老年代,永远带,jdk1.8及今后堆内存被分成了新生代和老年代。新生代的地区又分为eden区,s0区,s1区,默许比例是8:1:1,元空间能够明白为直接的物理内存
迎接关注
分布式系统一致性问题与Raft算法(上)