大家在平时的开发过程中是否遇到过StackOverflowErrorOutOfMemoryError等类似的内存溢出错误呢?大家又是怎么解决这个问题的?再来,大家在面试过程中有没有被面试官提问过jvm的内部构造及如何优化的夺命连环call呢?今天就让我们来一探究竟,先从jvm的内部构造及原理说起,一步一步带大家解决jvm的优化问题。

虚拟机简介

虚拟机(Virtual Machine,简称VM)就是一台虚拟的计算机。它是一款软件,用来执行一系列虚拟计算机指令。大体上,虚拟机可以分为系统虚拟机和程序虚拟机。

  • 大名鼎鼎的visual boxvmware就属于系统虚拟机,他们完全是对物理计算机的仿真,提供了一个可运行完整操作系统的软件平台。
  • 程序虚拟机的代表就是java虚拟机(jvm),他专门为执行单个计算机程序而设计,在java虚拟机中执行的指令我们称为java字节码指令。

无论是系统虚拟机还是程序虚拟机,在上边运行的软件都被限制于虚拟机提供的资源中。虚拟机所在的位置:硬件的操作系统之上。虚拟机与JDKJRE的关系如图所示:

架构模型

Java编译器输入的指令流基本上是一种基于栈的指令集架构,另一种指令集架构则是基于寄存器的指令集架构。那么他们之间有什么区别呢?

栈式架构特点:

  • 设计和实现更简单,适用于资源受限的系统;
  • 避开了寄存器的分配难题,使用零地址指令方式分配;
  • 指令流中的指令大部分是零地址指令,其执行过程依赖于操作栈。指令集更小,编译器容易实现;
  • 不需要硬件支持,可移植性好,更好实现跨平台。

寄存器架构特点:

  • 典型的应用是x86的二进制指令集:比如传统的PC以及AndroidDavlik虚拟机;
  • 指令集架构则完全依赖于硬件,可移植性差;
  • 性能优秀和执行更高效;
  • 花费更小的指令去完成一项操作;
  • 基于寄存器架构的指令集往往都以一地址指令、二地址指令和三地址指令为主。

机器指令是机器语言的一条语句,是一组有意义的二进制代码,一条机器指令通常分为两个部分:操作码和地址码。操作码指出该指令应该执行什么样的操作,代表了该指令的功能。地址码指出该指令操作的对象,给出被操作对象的地址。零地址指令指机器指令中操作数地址的个数为0,一地址指令指机器指令中操作数地址的个数为1,以此类推。

由于跨平台性的设计,java的指令都是根据栈来设计的,不同平台的cpu架构不同,所以不能设计为基于寄存器的。

举例:同样执行2+3的逻辑操作,其指令分别如下:

基于栈的计算流程(以Java虚拟机为例--idea中控制台使用javap -v XXX.class执行)

 0: iconst_2  //常量2入栈
1: istore_1 //将2从操作数栈存储到局部变量表 第1个位置
2: iconst_3 //常量3入栈
3: istore_2 //将2从操作数栈存储到局部变量表 第2个位置
4: iload_1 //位置为1的数据压入操作数栈
5: iload_2 //位置为2的数据压入操作数栈
6: iadd //常量2,3出栈,执行相加,并将结果压入操作数栈顶
7: istore_3 //结果5存到局部变量表 第三个位置
8: return

基于寄存器的计算流程:

mov eax,2  //将eax寄存器的值设为1
add eax,3 //使eax寄存器的值加3
java虚拟机的生命周期

虚拟机的启动:Java虚拟机的启动是通过引导类加载器创建一个初始类来完成的,这个类是由虚拟机的具体实现指定的。

虚拟机的执行:虚拟机的任务是执行java程序,其真正执行的是一个叫做java虚拟机的进程。

虚拟机的退出:

  1. 程序正常执行结束;
  2. 程序在执行过程中遇到了异常或者错误而异常终止;
  3. 操作系统出现错误而导致java虚拟机进程终止;
  4. 线程调用Runtime类或者System类的exit方法,或者Runtime类的halt方法,并且java安全管理器也允许这次exit或halt操作;
  5. JNI(Java Native Interface)规范描述了用JNI Invocation API来加载或卸载java虚拟机时,java虚拟机的退出情况。
常见的JVM

如果说java是跨平台的语言,那jvm就是跨语言的平台。只要是将该语言的文件遵循jvm的规范编译成jvm可以识别的字节码文件,就可以在jvm上运行。jvm的特点:一次编译,到处运行;自动内存管理;自动垃圾回收功能。

HotSpot、JRockit与J9并称三大主流JVM:

HotSpot VM:从JDK1.3开始使用,到现在OpenJDK中也在使用。采用解释器与即时编译器并存的架构,拥有成熟的热点代码探测技术和GC机制。所谓热点探测技术有以下两个方面的体现:一、通过计数器找到最具编译价值的代码,触发即时编译或者栈上替换功能--机器指令(cpu可以直接执行的指令)本地缓存;二、即时编译器和解释器协同工作,在最优化的程序响应时间与最佳执行性能之间平衡。

前端编译器(javac或者Eclipse JDT中的增量式编译器)把Java代码编译成字节码,字节码是可以发送给任何平台并且能在那个平台上运行的独立于平台的代码。

即时编译器(JIT compiler,just-in-timecompiler)是一个把Java的字节码(包括需要被解释的指令的程序)转换成可以直接发送给处理器(processor)的指令的程序。

JRockit VM:最初属于BEA公司,2008年被Oracle收购。它专注于服务器端应用,所以不太关注程序的启动速度,里边不包含解析器,号称是世界上最快的JVM。它提供的Mission Control服务套件,是一组以极低的开销来监控、管理和分析生产环境中的应用程序的工具。它包括三个独立的应用程序:内存泄漏监测器(Memory Leak Detector)、JVM运行时分析器(Runtime Analyzer)和管理控制台(Management Console)。

J9 VMJ9IBM开发的一个高度模块化的JVM,在许多平台上,IBM J9 VM都只能跟IBM产品一起使用。2017年IBM发布开源的OpenJ9,并贡献给 Eclipse 基金会。

非主流JVM介绍:

Azul VM: 是Azul system 公司在Hot Spot基础上进行的改进,是运行在其公司专有的硬件上,一个Azul VM 实例,都可以管理数十个CPU以及数百G的内存资源,而且通过巨大内存范围内,实现可控的GC事件以及垃圾回收。

Graal VM: 是一个高性能的通用虚拟机,可以运行使用JavaScriptPython 3RubyR,基于JVM的语言以及基于LLVM的语言开发的应用。GraalVM消除了编程语言之间的隔离性,并且通过共享运行时增强了他们的互操作性。它可以独立运行,也可以运行在OpenJDKNode.jsOracleMySQL等环境中。它的口号“Run Programs Faster Anywhere”。

HotSpot的整体架构图

如图所示为HotSpot的架构简图,接下来我们会按照该图的执行顺序说一下JVM里边的具体细节,如果你有不同的意见或者更好的idea,欢迎联系阿Q:可以关注gzh“阿Q说代码”,也可以加阿Q好友qingqing-4132,阿Q期待你的到来!

后台留言领取java干货资料:学习笔记与大厂面试题

JVM集合之开篇点题的更多相关文章

  1. JVM规范系列开篇:为什么要读JVM规范?

    许多人知道类加载机制.JVM内存模型,但他们可能不知道什么是<Java虚拟机规范>.对于Java开发来说,<Java虚拟机规范>才是最为官方.准确的一个文档,了解这个规范可以让 ...

  2. JVM基础系列开篇:为什么要学虚拟机?

    跟许多人一样,我一开始接触 Java 虚拟机只是因为面试需要用到,所以硬着头皮看看.所以很多人对于为什么要学虚拟机这个问题,他们的答案都是:因为面试.但我经过了几年的学习和实战,我发现其实学习虚拟机并 ...

  3. 系统优化怎么做-JVM优化之开篇

    大家好,这里是「聊聊系统优化 」,并在下列地址同步更新 博客园:http://www.cnblogs.com/changsong/ 知乎专栏:https://zhuanlan.zhihu.com/yo ...

  4. JVM基础系列第9讲:JVM垃圾回收器

    前面文章中,我们介绍了 Java 虚拟机的内存结构,Java 虚拟机的垃圾回收机制,那么这篇文章我们说说具体执行垃圾回收的垃圾回收器. 总的来说,Java 虚拟机的垃圾回收器可以分为四大类别:串行回收 ...

  5. JVM基础系列第8讲:JVM 垃圾回收机制

    在第 6 讲中我们说到 Java 虚拟机的内存结构,提到了这部分的规范其实是由<Java 虚拟机规范>指定的,每个 Java 虚拟机可能都有不同的实现.其实涉及到 Java 虚拟机的内存, ...

  6. JVM基础系列第5讲:字节码文件结构

    温馨提示:此篇文章长达两万字,图片50多张,内容非常多,建议收藏后再看. 前面我们说到 Java 虚拟机使用字节码实现了跨平台的愿景,无论什么系统,我们都可以使用 Java 虚拟机解释执行字节码文件. ...

  7. JVM规范系列第2章:Java虚拟机结构

    本规范描述的是一种抽象化的虚拟机的行为,而不是任何一种(译者注:包括 Oracle 公司自己的 HotSpot 和 JRockit 虚拟机)被广泛使用的虚拟机实现. 记住:JVM规范是一种高度抽象行为 ...

  8. 【集合框架】Java集合框架综述

    一.前言 现笔者打算做关于Java集合框架的教程,具体是打算分析Java源码,因为平时在写程序的过程中用Java集合特别频繁,但是对于里面一些具体的原理还没有进行很好的梳理,所以拟从源码的角度去熟悉梳 ...

  9. JVM基础系列第15讲:JDK性能监控命令

    查看虚拟机进程:jps 命令 jps 命令可以列出所有的 Java 进程.如果 jps 不加任何参数,可以列出 Java 程序的进程 ID 以及 Main 函数短名称,如下所示. $ jps 6540 ...

随机推荐

  1. DVWA之Reflected XSS(反射型XSS)

    目录 Low Medium High Impossible Low 源代码: <?php header ("X-XSS-Protection: 0"); // Is ther ...

  2. 利用 ROP 技术绕过 DEP 保护的一次简单尝试

    \x 01 前言 DEP是数据执行保护的英文缩写,全称为Data Execution Prevention.数据执行保护(DEP) 是一套软硬件技术,能够在内存上执行额外检查以帮助防止在系统上运行恶意 ...

  3. PHP中文转拼音扩展

    Pinyin 基于 CC-CEDICT 词典的中文转拼音工具,更准确的支持多音字的汉字转拼音解决方案. 安装 使用 Composer 安装: $ composer require "over ...

  4. 百度地图api逆地址解析 PHP

    一.说明:逆地址查询就是根据经纬度信息获取地址位置信息 二.参数:$lat:纬度值 ,$lng:经度值 ,$ak = 自己的AK:(百度地图开放平台对应ak链接:http://lbsyun.baidu ...

  5. PowerBI开发 第十九篇:基于Page创建Tooltip

    在PowerBI 报表中,常规的Tooltip是一段文本,当光标悬停在Visual上,Visual上方会自动显示Tooltip的文本.PowerBI 支持用户自定义内容丰富的Tooltip,用户通过创 ...

  6. Vue.js源码解析-从scripts脚本看vue构建

    目录 1. scripts 脚本构建 1.1 dev 开发环境构建过程 1.1.1 配置文件代码 1.1.2 如何进行代码调试? 1.2 build 生产环境构建过程 1.2.1 scripts/bu ...

  7. BUAA-OO-第三单元总结

    面向对象第三单元JML总结 JML理论基础及工具链梳理 JML语言理论基础 JML语言是对于JAVA进行规格化设计的一种表述语言,他能以一种统一化语言,逻辑性强的格式,向程序设计者描述这一方法实现的功 ...

  8. CRM帮助B2B企业持续改善战略决策「上篇」

    数据一直都是企业和客户的热点话题.客户期望得到更加个性化的感受,企业则期望使用数据来持续改善战略决策和给予更好的服务 B2B企业如何更合理地利用客户资料: 数据采集 长期以来,B2C行业的企业都是通过 ...

  9. LVHA爱恨原则

    关于link 和 visited是否访问过,讲得应该是对浏览器而言该网页之前是否访问过, 而不是只对单次生成页面而言

  10. 深入源码,深度解析Java 线程池的实现原理

    java 系统的运行归根到底是程序的运行,程序的运行归根到底是代码的执行,代码的执行归根到底是虚拟机的执行,虚拟机的执行其实就是操作系统的线程在执行,并且会占用一定的系统资源,如CPU.内存.磁盘.网 ...