1 HotSpot VM的历史

SUN/Oracle JDK中使用的JVM是HotSpot VM.

SUN JDK从1.3.1版本开始采用HotSpot虚拟机, 并于2006年底开源, 主要使用C++实现, JNI接口部分用C实现.

HotSpot是比较新的JVM, 用来替代JIT (Just in Time, 即时编译), 可以大大提高Java的运行性能 —— 通过下述方法提高性能:

Java起初是将源代码编译class字节码在虚拟机上执行, 速度较慢;

HotSpot将常用的部分代码编译为本地(native)代码, 显著提高性能.

HotSpot JVM参数分为标准参数(standard options)、非标准参数(non-standard options) 以及非稳定参数, 可参考: 关于JVM的垃圾回收(GC) 这可能是你想了解的4.1 参数名称的说明.

2 HotSpot VM 概述

HotSpot包括一个解释器和两个编译器(client和server, 实际运行中选择其一即可, 大多选择server), 解释与编译混合执行模式, 默认启动解释执行.

server模式下应用程序启动较慢, 占用内存多, 但执行效率高, 其适用于服务器端需要长期执行的应用;

client模式下应用程序启动较快, 占用内存小, 但执行效率较低, 默认情况下不进行动态编译, 适用于桌面应用程序.

(1) 查看 JVM 的启动模式:

# 使用解释与编译混合的模式
java -version
java version "1.8.0_162"
Java(TM) SE Runtime Environment (build 1.8.0_162-b12)
Java HotSpot(TM) 64-Bit Server VM (build 25.162-b12, mixed mode)
# mixed mode 解释与编译混合的模式, 是默认使用的模式.
# 使用纯解释模式
java -Xint -version
java version "1.8.0_162"
Java(TM) SE Runtime Environment (build 1.8.0_162-b12)
# interpreted mode 纯解释模式, 即禁用JIT编译.
# 使用纯编译模式
java -Xcomp -version
java version "1.8.0_162"
Java(TM) SE Runtime Environment (build 1.8.0_162-b12)
Java HotSpot(TM) 64-Bit Server VM (build 25.162-b12, compiled mode)
# compiled mode 纯编译模式, 如果方法无法编译, 则回退到解释模式执行无法编译的方法.

2.1 编译器

Java源代码被编译器编译成class字节码文件, 字节码在运行时可以被动态编译(JIT)成本地代码, 前提是解释与编译混合执行模式且虚拟机不是刚启动.

2.2 解释器

解释器用来解释class字节码文件, Java是解释型语言(区别于编译型语言).

2.3 解释型语言 VS 编译型语言

计算机不能直接理解执行高级语言, 只能直接执行机器语言, 所以必须将高级语言翻译成机器语言再执行.

翻译的方式有两种 —— 编译和解释, 两者只是翻译的时间不同:

① 解释型语言: 不需要提前翻译 —— 例如Java语言, 在运行时才翻译, 再由专门的解释器解释执行 —— 每执行一次就要翻译一次, 效率较低.

优点: 可移植性好, 只要有解释环境, 就可以在不同的操作系统上运行. 比如在解释执行时可以动态改变变量的类型、修改程序以及在程序中插入良好的调试诊断等信息, 将解释器移植到不同的系统上,则程序不用改动就可以在移植了解释器的系统上运行。

缺点: 运行需要解释环境, 运行速度较慢, 占用的资源更多 —— 因为不仅要为用户程序分配空间, 解释器本身也要占用一定的系统资源. 其封装了底层代码, 程序严重依赖平台, 不能同C++那样直接操作底层.

代表: 一些网页脚本、服务器脚本等对速度要求不高, 却对不同系统平台间的兼容性有要求的程序通常使用解释性语言, 如Java、JavaScript、Perl、Python、Ruby、MATLAB等.

② 编译型语言: 编写的程序在运行前, 需要通过编译器将代码编译成机器语言(二进制文件), 然后直接由相应的操作系统执行.

编译和执行是分开的, 但不能跨平台. 例如 C++ 编译成的 exe 文件, 运行时不需再次编译, 直接使用编译的结果即可 —— 效率较高.

因为不同的操作系统识别的二进制文件是不同的, 所以编译型语言的程序在移植后, 需要重新编译(如Windows下的C程序编译成exe文件, Linux下要编译成erp文件).

优点: 运行速度快, 代码效率高, 同等条件下对系统要求较低.

缺点: 代码需要经过编译才能运行, 可移植性差 —— 只能在兼容的操作系统上运行.

代表: 像开发操作系统、大型应用程序、数据库系统等时都使用编译型语言, 如C、C++、Pascal等.

3 动态编译

3.1 什么是动态编译

动态编译 (compile during run-time), 英文称 Dynamic compilation, Just In Time (即时编译) 也有此意.

HotSpot VM对字节码的编译不是在程序运行前, 而是在程序运行过程中编译的.

HotSpot VM中有一个监视器 (Profile Monitor), 用来监视程序的运行状况.

Java字节码 (class文件) 是以解释的方式被加载到虚拟机中 (默认启动时就解释执行), 程序运行过程中, 使用频率高、对程序的性能影响重要的代码, 称之为热点 (hotspot), HotSpot VM会把这些热点动态地编译成机器码 (native code), 同时对机器码进行优化, 从而提高运行效率. 对使用频率较低的代码, HotSpot VM就不会编译.

比如指令的重排序, 使用volatile关键字可以禁止重排序等类似的操作都是在这个编译阶段进行的.

3.2 HotSpot VM对字节码的处理方式

① 不编译: 字节码加载到虚拟机中时的状态, 也就是虚拟机执行时再编译;

② 编译: 把字节码编译成本地代码, 虚拟机执行时已经编译好了, 无需再次编译;

③ 编译并优化: 不但把字节码编译成本地代码, 而且还进行了优化.

具体如何处理, 都是由监视器 (Profile Monitor) 决定的.

3.3 为什么不静态编译

为什么不采取将字节码直接变异成本地代码, 然后再装载到虚拟机中?

① 动态编译器在许多方面比静态编译器优越 —— 静态编译器通常很难预知程序运行过程中最需要优化的代码.

② 函数调用是很浪费系统时间的, 因为有许多进出栈操作. 因此有一种优化办法, 就是把原来的函数调用通过编译, 改为非函数调用 —— 将函数代码直接嵌到调用的地方, 变为顺序执行.

③ 面向对象的语言支持多态, 静态编译无法确定程序调用的到底是超类的哪些实现子类的方法, 因为多态是在程序运行中才能具体确定的.

参考资料

OpenJDK和Sun/OracleJDK 区别 与联系

【Language】解释性语言和编译型语言的区别和不同

版权声明

作者: 马瘦风

出处: 博客园 马瘦风的博客

您的支持是对博主的极大鼓励, 感谢您的阅读.

本文版权归博主所有, 欢迎转载, 但请保留此段声明, 并在文章页面明显位置给出原文链接, 否则博主保留追究相关人员法律责任的权利.

关于HotSpot VM以及Java语言的动态编译 你可能想知道这些的更多相关文章

  1. OSGi 系列(一)之什么是 OSGi :Java 语言的动态模块系统

    OSGi 系列(一)之什么是 OSGi :Java 语言的动态模块系统 OSGi 的核心:模块化.动态.基于 OSGi 就可以模块化的开发 java 应用,模块化的部署 java 应用,还可以动态管理 ...

  2. OSGi是什么:Java语言的动态模块系统(一)

    OSGi是什么 OSGi亦称做Java语言的动态模块系统,它为模块化应用的开发定义了一个基础架构.OSGi容器已有多家开源实现,比如Knoflerfish.Equinox和Apache的Felix.您 ...

  3. [改善Java代码]慎用动态编译

    建议17: 慎用动态编译 //=========这篇博文暂时理解不透......... 动态编译一直是Java的梦想,从Java 6版本它开始支持动态编译了,可以在运行期直接编译.java文件,执行. ...

  4. Java为什么称为动态编译?

    Java在程序运行时产生Java类并编译成.class文件.

  5. 014-通过JDB调试,通过HSDB来查看HotSpot VM的运行时数据

    一.JDB调试        在预发环境下进行debug时,时常因为工具和环境的限制,导致debug体验非常差,那么有什么方法能够简化我们进行debug的体验吗?JDB就是一种.        JDB ...

  6. (转载)JAVA动态编译--字节代码的操纵

    在一般的Java应用开发过程中,开发人员使用Java的方式比较简单.打开惯用的IDE,编写Java源代码,再利用IDE提供的功能直接运行Java 程序就可以了.这种开发模式背后的过程是:开发人员编写的 ...

  7. [Java入门笔记] Java语言简介

    前言 学习Java有一段时间了,但是一直缺少一个系统的思想,现在重新通过书籍中.网上的文章,视频等资料,整理与回顾Java的知识点. 言归正传,让我们先从了解Java语言开始. Java语言的由来 J ...

  8. Java语言的9个主要特性

    Java作为时下很流行的一门编程语言,受到很多人的热爱,那么它有哪些特性呢?一起来看看吧. 1.Java语言是简单的 Java语言的语法与C语言和C++语言很接近,使得大多数程序员很容易学习和使用.另 ...

  9. Java学习:注解,反射,动态编译

    狂神声明 : 文章均为自己的学习笔记 , 转载一定注明出处 ; 编辑不易 , 防君子不防小人~共勉 ! Java学习:注解,反射,动态编译 Annotation 注解  什么是注解 ? Annotat ...

随机推荐

  1. Qwt 编译 配置 使用

    QWT,全称是Qt Widgets for Technical Applications,是一个基于LGPL版权协议的开源项目,可生成各种统计图.它为具有技术专业背景的程序提供GUI组件和一组实用类, ...

  2. 3步永久性激活pycharm 亲测有效

    ----------破解后,有效时间会到2099年------------ 1.下载JAR包:此JAR包的目的就是让截获截止时间并骗过pycharm 链接:https://pan.baidu.com/ ...

  3. linux shell 发送qq邮件失败

    安装 发送邮件功能 yum -y install postfix yum -y install mailx 使用 mail -s “fsfds” @qq.com < hh 第二次返回此信息 您在 ...

  4. maven build时报错Failed to execute goal org.apache.maven.plugins:maven-surefire-plugin:2.12.4:test

    [INFO] BUILD FAILURE [INFO] ------------------------------------------------------------------------ ...

  5. 快排实现仿order by多字段排序

    class OrderBy(object): def __init__(self, sequence, *condition, **extra_condition): ""&quo ...

  6. ajax经典面试题

    1.什么是AJAX,为什么要使用Ajax(请谈一下你对Ajax的认识) 什么是ajax: AJAX是“Asynchronous JavaScript and XML”的缩写.他是指一种创建交互式网页应 ...

  7. SEED实验——return-to-libc实验

    实验概述 本实验的学习目标是让学生获得缓冲区溢出攻击的一种有趣变体——return-to-libc攻击实验的亲身体验.这种攻击可以绕过目前在主要linux操作系统中实现的现有保护方案.利用缓冲区溢出漏 ...

  8. Ooui.Wasm:浏览器中的.NET

    小型.NET Web框架Ooui作为Web程序集(WASM)在浏览器中完全运行 – 不需要服务器端的交互,涉及的所有文件都直接从浏览器执行,.NET Web框架Ooui可以作为其开发人员Frank A ...

  9. WordPress独立下载页面与演示插件:xydown

    我的博客是个资源分享的网站,所以需要提供下载,之前一直是在内容里直接添加个下载链接,感觉不是很美观,而且也麻烦,所以今天找了下看看有没有可以用的下载插件 xydown,这是一款可以独立下载页面与演示的 ...

  10. Javascript高级编程学习笔记(1)—— JS简介

    此系列文章,用于记录所学,如有错误欢迎指出. Javascript组成 1.核心(ECMAScript) 2.文档对象模型(DOM) 3.浏览器对象模型(BOM) 1.核心(ECMAScript) E ...