一文带你认识JVM

🚗🚗🚗今天给大家分享的关于JVM的一些基本认识。

清风的CSDN博客

🛩️🛩️🛩️希望我的文章能对你有所帮助,有不足的地方还请各位看官多多指教,大家一起学习交流!

✈️✈️✈️动动你们发财的小手,点点关注点点赞!在此谢过啦!哈哈哈!😛😛😛

目录

一、JVM简介 

1.1 JVM 发展简史 

1.1.1 Sun Classic VM

1.1.2 Exact VM  

1.1.3 HotSpot VM  

1.1.4 JRockit 

1.1.5 J9 JVM  

1.1.6 Taobao JVM(国产研发) 

二、JVM 运行流程

2.1 JVM执行流程

 三、JVM 运行时数据区

 3.1 堆(线程共享)

3.2 Java虚拟机栈(线程私有)

3.3 本地方法栈(线程私有)  

3.4 程序计数器(线程私有)   

3.5 方法区(线程共享) 

3.6 运行时常量池 


一、JVM简介 

       JVM 是 Java Virtual Machine 的简称,意为 Java虚拟机。 虚拟机是指通过软件模拟的具有完整硬件功能的、运行在一个完全隔离的环境中的完整计算机系统,常见的虚拟机:JVM、VMwaveVirtual Box

JVM 和其他两个虚拟机的区别:
  • VMwaveVirtualBox是通过软件模拟物理CPU的指令集,物理系统中会有很多的寄存器。
  • JVM则是通过软件模拟Java字节码的指令集,JVM中只是主要保留了PC寄存器,其他的寄存器都进行了裁剪。

JVM 是一台被定制过的现实当中不存在的计算机。

1.1 JVM 发展简史 

1.1.1 Sun Classic VM

       早在 1996 Java1.0 版本的时候, Sun 公司发不了一款名为 Sun Classic vm java 虚拟机,它同时也是世界上第一款商业java 虚拟机, jdk1.4 时完全被淘汰。 这款虚拟机内部只提供解释器。 如果使用JIT 编译器,就需要进行外挂,但是一旦使用了 JIT 编译器, JIT 就会接管虚拟机的执行系统。解释器就不再工作。解释器和编译器不能配合工作,现在 Hotspot 内置了此虚拟机。

1.1.2 Exact VM  

       为了解决上一个虚拟机问题, jdk1.2 时, sun 提供了此虚拟机。 Exact 具备现代高性能虚拟机的雏形,包含了一下功能:
  • 热点探测(将热点代码编译为字节码加速程序执行)。
  • 编译器与解析器混合工作模式。
只在 Solaris 平台短暂使用,其他平台上还是 classic vm,英雄气短,终被Hotspot 虚拟机替换。

1.1.3 HotSpot VM  

        最初由一家名为 “Longview Technologies” 的小公司设计,1997年,此公司被 Sun 收购; 2009 年, Sun 公司被甲骨文收购,JDK1.3时, HotSpot VM 成为默认虚拟机。
目前 HotSpot 占用绝对的市场地位,称霸武林。 不管是现在仍在广泛使用JDK6 ,还是使用比较多的 JDK8 中,默认的虚拟机都是 HotSpot、 Sun/Oracle JDK和 OpenJDK 的默认虚拟机。从服务器、桌面到移动端、嵌入式都有应用。 名称中的HotSpot 指的就是它的热点代码探测技术。它能通过计数器找到最具编译价值的代码,触发即时编译(JIT) 或栈上替换,通过编译器与解释器协同工作,在最优化的程序响应时间与最佳执行性能中取得平衡。

1.1.4 JRockit 

        JRockit 是专注于服务器端应用,目前在 HotSpot 的基础上,移植 JRockit 的优秀特性。 它可以不太关注程序的启动速度,因此JRockit 内部不包含解析器实现,全部代码都靠即时编译器编译后执行。大量的行业基准测试显示,JRockit JVM 是世界上最快的 JVM。 使用JRockit 产品,客户已经体验到了显著的性能提高(一些超过了 70% )和硬件成本的减少(达50%)。
优势:全面的 Java 运行时解决方案组合。
JRockit  面向延迟敏感型应用的解决方案  JRockit Real Time  提供以毫秒或微秒级的 JVM 响应时间,适合财务、军事指挥、电信网络的需要。
MissionControl 服务套件,它是一组以极低的开销来监控、管理和分析生产环境中的应用程序的工具。2008, BEA Oracle 收购。 Oracle表达了整合两大优秀虚拟机的工作,大致在 JDK8 中完成。整合的方式是在 HotSpot 的基础上,移植JRockit 的优秀特性。

1.1.5 J9 JVM  

全称: IBM Technology for Java Virtual Machine ,简称 IT4J ,内部代号: J9
市场定位于 HotSpot 接近,服务器端、桌面应用、嵌入式等多用途 JVM ,广泛用于 IBM 的各种 Java产品。 目前,有影响力的三大商用虚拟机之一,也号称是世界上最快的 Java 虚拟机 ( IBM 自己的产品上稳定 )。 2017 年左右, IBM 发布了开源 J9 VM ,命名 OpenJ9 ,交给 Eclipse 基金会管理,也称为 Eclipse  OpenJ9

1.1.6 Taobao JVM(国产研发) 

AliJVM 团队发布。阿里,国内使用 Java 最强大的公司,覆盖云计算、金融、物流、电商等众多领域,需要解决高并发、高可用、分布式的复合问题。有大量的开源产品。 基于OpenJDK 开发了自己的定制版本 AlibabaJDK, 简称 AJDK 。是整个阿里 JAVA 体系的基石。基于OpenJDK HotSpot JVM 发布的国内第一个优化、深度定制且开源的高性能服务器版 Java 虚拟机,它具有以下特点:
  • 创新的GCIH(GC invisible heap)技术实现了off-heap,即将生命周期较长的Java对象从heap中移heap之外,并且GC不能管理GCIH内部的Java对象,以此达到降低GC的回收评率和提升GC的回收效率的目的。
  • GCIH中的对象还能够在多个Java虚拟机进程中实现共享。
  • 使用crc32指令实现JVM intrinsic降低JNI的调用开销;
  • PMU hardwareJava profiling tool和诊断协助功能;
  • 针对大数据场景的ZenGC 
taobao JVM 应用在阿里产品上性能高,硬件严重依赖  intel  cpu, 损失了兼容性,但提高了性能,目前已经在淘宝、天猫上线,把Oracle 官方 JVM 版本全部替换了。

二、JVM 运行流程

JVM Java 运行的基础,也是实现一次编译到处执行的关键,那么 JVM 是如何执行的呢?

2.1 JVM执行流程

        程序在执行之前先要把  java  代码转换成字节码( class 文件), JVM 首先需要把字节码通过一定的方式  类加载器   把文件加载到内存中 运行时数据区   ,而字节码文件是 JVM 的一套指令集规范,并不能直接交个底层操作系统去执行,因此需要特定的命令解析器 执行引擎 将字节码翻译成底层系统指令再交由 CPU 去执行,而这个过程中需要调用其他语言的接口 本地库接口 来实现整个程序的功能,这就是这 4 个主要组成部分的职责与功能。

总结来看, JVM 主要通过分为以下 4 个部分,来执行 Java 程序的,它们分别是:
  • 类加载器
  • 运行时数据区
  • 执行引擎
  • 本地库接口

 三、JVM 运行时数据区

JVM 运行时数据区域也叫内存布局,但需要注意的是它和 Java 内存模型( (Java Memory Model ,简称JMM)完全不同,属于完全不同的两个概念,它由以下 5 大部分组成:

 3.1 堆(线程共享)

堆的作用:程序中创建的所有对象都在保存在堆中。
堆里面分为两个区域:新生代和老生代,新生代放新建的对象,当经过一定 GC 次数之后还存活的对象会放入老生代。新生代还有 3 个区域:一个 Endn + 两个 Survivor S0/S1 )。

垃圾回收的时候会将 Endn 中存活的对象放到一个未使用的 Survivor 中,并把当前的 Endn 和正在使用的 Survivor 清楚掉。(关于垃圾回收,我后续会给大家详细介绍)。

3.2 Java虚拟机栈(线程私有)

         Java 虚拟机栈的作用: Java 虚拟机栈的生命周期和线程相同, Java 虚拟机栈描述的是 Java 方法执行的内存模型,每个方法在执行的同时都会创建一个栈帧(Stack Frame )用于存储局部变量表、操作数栈、动态链接、方法出口等信息。咱们常说的堆内存、栈内存中,栈内存指的就是虚拟机栈。
Java 虚拟机栈中包含了以下 4 部分:

  • 局部变量表: 存放了编译器可知的各种基本数据类型(8大基本数据类型)、对象引用。局部变量表所需的内存空间在编译期间完成分配,当进入一个方法时,这个方法需要在帧中分配多大的局部变量空间是完全确定的,在执行期间不会改变局部变量表大小。简单来说就是存放方法参数和局部变量。
  • 操作栈:每个方法会生成一个先进后出的操作栈。
  • 动态链接:指向运行时常量池的方法引用。
  • 方法返回地址:PC 寄存器的地址。

3.3 本地方法栈(线程私有)  

 本地方法栈和虚拟机栈类似,只不过 Java 虚拟机栈是给 JVM 使用的,而本地方法栈是给本地方法使用的。

3.4 程序计数器(线程私有)   

程序计数器的作用:用来记录当前线程执行的行号的。
程序计数器是一块比较小的内存空间,可以看做是当前线程所执行的字节码的行号指示器。 如果当前线程正在执行的是一个Java 方法,这个计数器记录的是正在执行的虚拟机字节码指令的地址。
如果正在执行的是一个 Native 方法,这个计数器值为空。 程序计数器内存区域是唯一一个在JVM 规范中没有规定任何 OOM 情况的区域!

3.5 方法区(线程共享) 

方法区的作用:用来存储被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等数据的。

3.6 运行时常量池 

运行时常量池是方法区的一部分,存放字面量与符号引用。
  • 字面量 : 字符串(JDK 8 移动到堆中) final常量、基本数据类型的值。
  • 符号引用 : 类和结构的完全限定名、字段的名称和描述符、方法的名称和描述符。

小结 


🚗🚗🚗好啦,今天的分享就到这里,别说还挺晕的,哈哈哈。多看几遍就行啦!也有可能是我没有给大家表述清楚,有什么问题欢迎大家指出。

🎉🎉🎉创作不易,还希望各位大佬支持一下!

✈️✈️✈️点赞,你的认可是我创作的动力!

⭐⭐⭐收藏,你的青睐是我努力的方向!

✏️✏️✏️评论:你的意见是我进步的财富!

  • 28
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

..清风

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值