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,元空间可以理解为直接的物理内存

欢迎关注

参考博客

官方介绍

[1]https://www.oracle.com/technetwork/java/javase/tech/index.html

[2]https://mp.weixin.qq.com/s/Qh9e3bNTcNRaYOft9n7rvg

最新文章

  1. CDH安装失败了,如何重新安装
  2. [原创]首次制作JQueryUI插件-Timeline时间轴
  3. Dynamics AX 2012 R3 Demo 安装与配置 - 配置安装环境 (Step 1)
  4. 配置java环境
  5. jemalloc源码结构分析(三):arena_malloc_small内存分布
  6. python 探索(四) Python CookBook 系统管理
  7. 一键cobbler批量安装脚本
  8. 老李分享:loadrunner操作mysql数据库
  9. Docker快速搭建LNMP环境
  10. 使用openssl创建一个自签名https证书,并配置到nginx里面
  11. CocoaPods出错
  12. MVC Autofac依赖注入
  13. VMware安装Windows注意
  14. elasticsearch分析系列
  15. 补发9.27“天天向上”团队Scrum站立会议
  16. UVa 1637 纸牌游戏(全概率公式)
  17. P1314 聪明的质监员
  18. Distributed Denial of Service
  19. 【转载】python计算文件的行数和读取某一行内容的实现方法
  20. [yii2]urlmanger

热门文章

  1. java package 包 学习笔记
  2. [ZJOI2019]麻将(DP+有限状态自动机)
  3. [LC] 1048. Longest String Chain
  4. 56)PHP,模型类的设计思想
  5. Datagridview 实现二维表头和行合并
  6. linux下常用命令查看端口占用
  7. spring boot web 开发及数据库操作
  8. Traffic Network in Numazu
  9. 火车进出栈 java
  10. 牛客-Forsaken的数列(Treap)