1 JVM的基本特性

1.1 基于栈(Stack-based): 不同于Intel x86和ARM等比较流行的计算机处理器都是基于寄存器(register)架构,JVM是基于栈执行的。

1.2 符号引用(Symbolic reference): 编译后的.class文件中,除基本类型外的所有Java类型都是通过符号引用取得关联的,而非显式的基于内存地址的引用。

【符号引用以一组符号来描述所引用的目标,符号可以是任何形式的字面量。例如,在Class文件中它以CONSTANT_Class_info、CONSTANT_Fieldref_info、CONSTANT_Methodref_info等类型的常量出现。

在编译时,java类还没有被加载到内存中,所以并不知道所引用的类的实际地址,因此只能使用符号引用来代替;在解析阶段,Java虚拟机会把类的二进制数据中的符号引用替换为直接引用(指向内存地址)】

1.3 垃圾回收机制: 类的实例通过用户代码进行显式创建,但却通过垃圾回收机制自动销毁。

1.4 通过明确清晰基本类型确保平台无关性: 像C/C++等传统编程语言对于int类型数据在同平台上会有不同的字节长度。JVM却通过明确的定义基本类型的字节长度来维持代码的平台兼容性,从而做到平台无关。

1.5 网络字节序(Network byte order): 是TCP/IP中规定好的一种数据表示格式。Java class文件的二进制表示使用的是网络字节序,即基于big endian的字节序。

【字节序,即字节在电脑中存放时的序列与输入(输出)时的序列是先到的在前还是后到的在前。 Little endian:将低序字节存储在起始地址; Big endian:将高序字节存储在起始地址】

2.Java字节码在JVM中的运行

2.1 编译机制

Java字节码无法直接直接,需要JVM将其翻译成机器码。

在 HotSpot 里面,翻译过程有两种形式:第一种是解释执行,相当于同声传译,即每解析一条字节码,便翻译成机器码并执行;第二种是即时编译(Just-In-Time compilation,JIT),则相当于线下翻译,即将整个方法中所包含的字节码统一翻译成机器码后在执行。前者的优势在于无需等待编译,而后者的优势在于实际运行速度更快。

HotSpot 默认采用混合模式,综合了解释执行和即时编译两者的优点。它会先解释执行字节码,而后将其中反复执行的热点代码,以方法为单位进行即时编译。

2.2 加载流程

执行 Java 代码首先需要将它编译而成的 class 文件加载到 Java 虚拟机的方法区中。实际运行时,执行引擎会执行方法区内的代码。每当调用一个 Java 方法,Java 虚拟机会在当前线程的 Java 方法栈中生成一个栈帧,用以存放局部变量以及字节码的操作数。这个栈帧的大小是提前计算好的,而且 Java 虚拟机不要求栈帧在内存空间里连续分布。当退出当前执行的方法时,不管是正常返回还是异常返回,JVM均会弹出当前栈帧,并将之舍弃。

3.加载Java类

JVM加载 Java 类的过程可分为三大步骤:加载、链接以及初始化。

3.1 加载

指通过类加载器查找字节流,创建类的过程。类加载器使用双亲委派模型,即接收到加载请求时,会先将请求转发给父类加载器。

3.2 链接

指将创建成的类合并至 JVM中,使之能够执行的过程。

链接还分验证(验证被加载类是否满足 JVM约束)、准备(为被加载类静态字段分配内存)和解析(将被加载类中的符号引用解析成为实际引用)三个阶段。其中,JVM规范并不要求解析阶段一定要在链接步骤中完成。

3.3 初始化

为常量赋值,以及执行 <clinit> 方法的过程。类的初始化仅会被执行一次,这个特性被用来实现单例的延迟初始化。

4.垃圾回收

垃圾回收器采用可达性分析来探索所有存活的对象。它从一系列根对象出发,标记所有被引用的对象。为了防止在标记过程中堆栈的状态发生改变,JVM采取STW(Stop-The-World) 操作,暂停其他非垃圾回收线程。

通常来说,JVM采用分代回收的思想,将堆划分为新生代和老年代,并且在不同代中应用不同的垃圾回收算法。新生代再划分为 Eden 区和两个大小一致的 Survivor 区。在Minor GC 中,Eden 区和非空 Survivor 区的存活对象会被复制到空的 Survivor 区中,当 Survivor 区中的存活对象复制次数超过一定数值时,它将被晋升至老年代。因为 Minor GC 只针对新生代进行垃圾回收,所以需要考虑从老年代到新生代的引用。为了避免扫描整个老年代,Java 虚拟机引入了名为卡表的技术,标出老年代对新生代引用的内存区域。

G1 垃圾回收器包含三个阶段(新生代GC、并发标记周期、混合GC);G1将堆划分为多个等大的区域,优先收集垃圾最多的区域,从而最大化垃圾回收的效益。

Java 11 中引入的实验性垃圾回收器 ZGC,仅在扫描可达对象时请求 Stop-The-World,暂停应用线程。因此,它宣称可将 GC 暂停时间控制在 10ms 以下。ZGC 暂时没有应用分代回收的思路,将整个堆空间看成一块,其代价是垃圾回收 CPU 消耗较高。

5.Java内存模式

在现代计算机系统中,代码通常不会按照书写顺序执行。造成这一情况的原因有三个,分别为编译器的重排序,处理器的乱序执行,以及内存系统的重排序。

以内存系统重排序为例,在多处理器体系架构下,每个处理器都可能缓存了一部分数据。由于时刻保持缓存数据与内存数据同步的性能代价太大,因此部分体系架构可能允许缓存数据与内存数据不同步。这对 Java 程序的影响便是,两个不同的 Java 线程在同一时间内看到的同一块内存地址中的值可能不同。

Java 内存模型是针对上述问题而提出的一套规范,用以允许 Java 程序员更为细致地定义 Java 程序的内存行为。它通过定义了一系列的 happens-before 操作,让应用程序开发者能够轻易地表达不同线程的操作之间的内存可见性。

在遵守 Java 内存模型的前提下,即时编译器以及底层体系架构能够调整内存访问操作,以达到性能优化的效果。如果开发者没有正确地利用 happens-before 规则,那么将可能导致数据竞争。

Java 内存模型是通过内存屏障来禁止重排序的。对于即时编译器来说,内存屏障将限制它所能做的重排序优化。对于处理器来说,内存屏障会导致缓存的刷新操作。

6. 参考文献

6.1 狼小战的博客《Java虚拟机必学之四大知识要点》

6.2 hello_史努比《java -- JVM的符号引用和直接引用》

6.3 百度百科《字节序》

JVM五大知识点的更多相关文章

  1. 「JVM」知识点详解一:JVM运行原理详解

    前言 JVM 一直都是面试的必考点,大家都知道,但是要把它搞清楚又好像不是特别容易.JVM 的知识点太散,不系统,今天带大家详细的了解一下jvm的运行原理. 正文 1 什么是JVM? JVM是Java ...

  2. 新鲜出炉!花了三天整理的JVM复习知识点,面试突击必备!

    此次JVM知识点包含以下几个部分 1.类加载机制 2.jvm运行时数据区 3.java对象内存布局 4.jvm内存模型 5.垃圾回收机制 6.垃圾收集器 7.问题排查 一 类加载机制 主要说的部分是这 ...

  3. 多图:一文带你入门掌握JVM所有知识点

    本JVM系列属于本人学习过程当中总结的一些知识点,目的是想让读者更快地掌握JVM相关的知识要点,难免会有所侧重,若想要更加系统更加详细的学习JVM知识,还是需要去阅读专业的书籍和文档. 本文主题内容: ...

  4. 大数据基础篇----jvm的知识点归纳-5个区和垃圾回收机制

    一直对jvm看了又忘,忘了又看的.今天做一个笔记整理存放在这里. 我们先看一下JVM的内存模型图: 上面有5个区,这5个区干嘛用的呢? 我们想象一个场景: 我们有一个class文件,里面有很多的类的定 ...

  5. JVM虚拟机知识点

    java -version 显示JDK 版本 Java HotSpot Client:1.5版本之后,热点探测,对加载的class文件做标记,对于频繁使用的class即时编译JIT本地缓存,不再重新进 ...

  6. 一文带你学会java的jvm精华知识点

    前言 本文分为20多个问题,通过问题的方式,来逐渐理解jvm,由浅及深.希望帮助到大家. 1. Java类实例化时,JVM执行顺序? 正确的顺序如下: 1父类静态代码块 2父类静态变量 3子类静态代码 ...

  7. jvm相关知识点

    1.hotspot虚拟机结构:类加载器.堆.栈.方法区.垃圾回收系统.执行引擎.本地方法栈.pc寄存器. 类加载器:负责将class文件从文件系统加载到方法区. 堆:存放对象的一块区域,所有线程共用. ...

  8. 图解 JVM 核心知识点(面试版)

    一.基本概念 1.1 OpenJDK 自 1996 年 JDK 1.0 发布以来,Sun 公司在大版本上发行了 JDK 1.1.JDK 1.2.JDK 1.3.JDK 1.4.JDK 5,JDK 6 ...

  9. 95%的技术面试必考的JVM知识点都在这,另附加分思路!

    概述:知识点汇总 jvm的知识点汇总共6个大方向:内存模型.类加载机制.GC垃圾回收是比较重点的内容.性能调优部分偏重实际应用,重点突出实践能力.编译器优化和执行模式部分偏重理论基础,主要掌握知识点. ...

随机推荐

  1. Confluence 6 升级自定义的站点和空间应用你的自定义布局

    当你升级你的 Confluence 到其他一个主要的 Confluence 发行版本的时候,你需要手动应用你修改过的任何全局或者空间级别的布局.除非有特殊的声明,针对一些非主要的 Confluence ...

  2. zoj3659

    #include<iostream> #include<algorithm> #include<cstring> #define ll long long #inc ...

  3. pycharm提示This inspection detects instance attribute definition outside __init__ method

    示例代码: class MiNiCarStore(CarStore): def createCar(self, typeName): self.carFactory = CarFactory() # ...

  4. echarts + timeline 显示多个options

    var option = { //timeline基本配置都写在baseoption 中 baseOption: { timeline: { //loop: false, axisType: 'cat ...

  5. 步步为营-94-GridView中的DropDownlist值得获取与绑定

    bug场景: 例如这种"计税方式"是下拉列表的,当选择"编辑"时候,数据会丢失 修改方式,前台对应修改 后台代码在databound时候给绑定值 测试效果

  6. 20165328 预备作业3 Linux安装及命令

    Linux安装及学习 Linux安装遇到的问题: 问题:在我开始安装虚拟机的时候,在安装过程中总会出现初始界面,且无法跳过,陷入死循环. 解决方法:我在网上百度搜索该问题之后得到了答案,第一个界面是要 ...

  7. Linux-server-sshd

    Linux-server-sshd 1:安装 OpenSSH 服务需要4 个软件包 openssh-5.3p1-114.el6_7.x86_64:包含OpenSSH 服务器及客户端需要的核心文件 op ...

  8. 据说是Flord算法

    贵有恒,何必三更起五更眠:最无益,莫过一日曝十日寒. 问题 C: Restoring Road Network 问题 C: Restoring Road Network 时间限制: 1 Sec  内存 ...

  9. C#线性表

    线性表是线性结构的抽象 线性结构的特点是结构中的数据元素之间存在一对一的线性关系 一对一的关系指的是数据元素之间的位置关系 (1)除第一个位置的数据元素外,其它数据元素位置的前面都只有一个数据元素 ( ...

  10. Android Studio 打包签名教程

    android studio apk第三方加固与签名,混淆打包 https://jingyan.baidu.com/article/f25ef2545386af482c1b828f.html Andr ...