HotSpot VM运行时
HotSpot VM运行时系统为HotSpot JIT编译器和垃圾收集器提供服务和通用API,同时还为VM提供启动、线程管理、JNI(Java本地接口)等基本功能。HotSpot VM运行时环境担当许多职责,具体如下:
1、命令行选项
通过命令行选项来配置HotSpot VM,相当于HotSpot VM的配置文件,主要包括选择哪个JIT编译器、何种垃圾收集器、Java Heap的大小等。命令行选项主要有3类:
1.1、标准选项(Standard Option)
标准选项是Java Virtual machine Specification要求所有Java虚拟机都实现的选项,它们在发行版之间保持稳定,但也可能在后续的发行版中被废除。
1.2、非标准选项(Nonstandard Option)
非标准选项(以-X为前缀)不保证、也不强制所有JVM实现都必须支持,它可能未经通知就在Java SDK发行版之间发生更改。
1.3、非稳定选项(Developer Option)
非稳定选项通常是为了特定需要而对JVM的运行进行校正,并且可能需要有系统配置参数的访问权限。与非标准选项一样,非稳定选项也可能不经通知就在发行版之间发生变动。
2、VM生命周期
HotSpot VM运行时系统负责启动和停止HotSpot VM。启动HotSpot VM的组件式启动器。HotSpot VM有若干个启动器。Unix/Linux上最常用的是java,Windows上是java和javaw。也可以通过JNT接口(JNI_CreateJavaVM)启动内嵌的JVM,另外还有一个网络启动器Javaws(Java Web Start)。
启动器启动HotSpot VM时会执行一系列操作。步骤概述如下:
(1)解析命令行选项
(2)设置堆的大小和JIT编译器
如果命令行没有明确设置堆的大小和JIT编译器,启动器则通过自动优化进行设置。
(3)设定环境变量如:LD_LIBRARY_PATH和CLASSPATH
(4)如果命令行有-jar选项,启动器则从指定JAR的manifest中查找Main-Class,否则从命令行读取Main-Class
(5)使用标准Java本地接口(Java Native Interface,JNI)方法JNI_CreateJavaVM在新创建的线程中创建HotSpot VM
(6)一旦创建并初始化号HotSpot VM,就会加载Java Main-Class,启动器也会从Java Main-Class中取得Java main方法的参数
(7)HotSpot VM通过JNI方法CallStartVoidMethod调用Java main方法,并将命令行选项传给它
3、VM类加载
(1)类加载阶段
对给定的Java类或者接口,类加载时会依据她的名字找到Java类的二进制字节流,定义Java类,然后创建代表这个类或者接口的java.lang.Class对象。HotSpot VM必须先加载它的所有超类和超接口。如果类的继承层次有错,HotSpot VM则会抛出ClassCircularityError。
链接的第一步是验证,检查类文件的语义、常量池符号以及类型。第二步是准备,它会创建静态字段,初始化为标准默认值,以及分配方法表。
如:int的标准默认值为0;public static int value=123,准备阶段将其初始化为0而不是123,value=123的赋值操作在内构造器<clinit>()中。
public static final int value=123,编译时会为value在字段属性表中生成ConstantValue,从而在准备阶段就被初始化成123。
初始化类,运行类构造器。初始化类需要首先初始化超类(不会初始化超接口)。
(2)类加载器委派
Java SE类加载器的层级查找顺序为启动类加载器、扩展类加载器及系统内加载器。系统类加载器是默认的应用程序类加载器,它加载Java类的main方法并从classpass上加载类。应用程序类加载器可以是Java SE系统自带的类加载器,或者由应用程序开发人员提供。扩展类加载器则由Java SE系统实现,它负责从JRE(Java Runtime Environment)的lib/ext目录下加载类。
(3)启动类加载器
启动类加载器是由HotSpot VM实现的,负责加载BOOTCLASSPATH路径中的类,如包含Java SE类库的rt.jar。
(4)类型安全
Java类或接口的名字为全限定名(包括包名)。Java的类型由全限定名何类加载器唯一确定。
(5)HotSpot类元数据
类加载时,HotSpot VM会在永久代创建类的内部表示instanceKlass或arrayKlass。instanceKlass应用了与之对应的java.lang.Class实例,后者是前者的Java镜像。HotSpot VM内部使用称为klassOop的数据结构访问instanceKlass。后缀“Oop”表示普通对象指针,所以klassOop是应用java.lang.Class的HotSpot内部抽象,它是指向Klass(与Java类对应的内部表示)的普通对象指针。
(6)内部的类加载数据
类加载过程中,HotSpot VM维护了3张散列表。SystemDictionary包含已加载的类,它将建立类名/类加载器(包括初始类加载器和定义类加载器)与klassOop对象之间的映射。muqian有在安全点事才能移除SystemDictionary中的元素。Placeholder-Table包含当前正在加载的类,它用于检查ClassCircularityError,多线程类加载器并行加载类时也会用到它。LoaderConstraintTable用于追踪类型安全检查的约束条件。这些散列表都需要加锁保证访问安全,在HotSpot VM中,这个锁称为SystemDictionary_lock。通常,HotSpot VM借助类加载器对象锁对加载类的过程进行序列化。
4、字节码验证
在链接时必须进行字节码验证以保证类型安全。
5、类数据共享
类数据共享的首要目的是减少启动时间,同时还可以节省内存空间。
6、解释器
HotSpot VM解释器是一种基于模板的解释器。JVM启动时,HotSpot VM运行时系统利用内部TemplateTable中的信息在内存中生成解析器。TemplateTable包含于每个字节码对应的机器代码,每个模板描述一个字节码。
7、异常处理
当与Java的语义约束冲突时,Java虚拟机会用异常通知程序。异常处理由HotSpot VM解释器、JIT编译器和其他HotSpot VM组件一起协作实现。异常处理主要有两种情形,同一方法中抛出和捕获异常;由调用方法捕获异常。异常可以由抛出字节码、VM内部调用返回、JNI调用返回或Java调用返回所引发。
8、线程管理
HotSpot VM的线程模型中,Java线程(java.lang.Thread实例)被一对一映射为本地操作系统线程。HotSpot VM内部以C++类JavaThread的实例表示java.lang.Thread实例,它包含其他的线程状态追踪信息。当java.lang.Thread启动时,HtoSpot VM创建与之相关联的JavaThread和OSThread对象(代表操作系统线程),最后是本地线程,依据线程关联是的参数,反射调用Thread类构造函数的Java代码,从而创建该对象。终止线程会释放所有已分配的资源,并从已知线程列表中移除JavaThread,然后调用OSThread和JavaThread的析构函数,当它的初始启动方法完成时,最终停止运行。
HotSpot VM运行时的更多相关文章
- HotSpot VM执行引擎的实现
Java代码的执行分类: 第一种是将源代码编译成字节码文件,然后再运行时通过解释器将字节码文件转为机器码执行 第二种是编译执行(直接编译成机器码).现代虚拟机为了提高执行效率,会使用即时编译技术(JI ...
- 第1篇-关于JVM运行时,开篇说的简单些
开讲Java运行时,这一篇讲一些简单的内容.我们写的主类中的main()方法是如何被Java虚拟机调用到的?在Java类中的一些方法会被由C/C++编写的HotSpot虚拟机的C/C++函数调用,不过 ...
- 转:什么是即时编译(JIT)!?OpenJDK HotSpot VM剖析
重点 应用程序可以选择一个适当的即时编译器来进行接近机器级的性能优化. 分层编译由五层编译构成. 分层编译提供了极好的启动性能,并指导编译的下一层编译器提供高性能优化. 提供即时编译相关诊断信息的JV ...
- 关于HotSpot VM以及Java语言的动态编译 你可能想知道这些
目录 1 HotSpot VM的历史 2 HotSpot VM 概述 2.1 编译器 2.2 解释器 2.3 解释型语言 VS 编译型语言 3 动态编译 3.1 什么是动态编译 3.2 HotSpot ...
- 解决IntelliJ IDEA控制台乱码问题[包含程序运行时的log4j日志以及tomcat日志乱码]
这里使用的IntelliJ IDEA版本为[IntelliJ IDEA 14.1.4]: 一.控制台打印的程序运行时的log4j日志中包含中文乱码 在IDEA安装目录的bin目录下找到名为" ...
- 基于Rust-vmm实现Kubernetes运行时
随着容器及K8s的广泛使用,越来越多的容器安全与隔离问题被暴露出来,如:容器逃逸.水平攻击.DDos攻击等严重威胁了办公和生产环境的安全与稳定,影响了业务的正常运行.安全容器技术孕育而生,产生了kat ...
- 我为Dexposed续一秒——论ART上运行时 Method AOP实现
转载于:http://weishu.me/2017/11/23/dexposed-on-art/ 两年前阿里开源了 Dexposed 项目,它能够在Dalvik上无侵入地实现运行时方法拦截,正如其介绍 ...
- 容器进阶:OCI与容器运行时
Blog:博客园 个人 什么是容器运行时(Container Runtime) Kubernetes节点的底层由一个叫做容器运行时的软件进行支撑,它负责比如启停容器 这样的事情.最广为人知的容器运行时 ...
- 乘风破浪,.Net Core遇见Dapr,为云原生而生的分布式应用运行时
Dapr是一个由微软主导的云原生开源项目,国内云计算巨头阿里云也积极参与其中,2019年10月首次发布,到今年2月正式发布V1.0版本.在不到一年半的时间内,github star数达到了1.2万,超 ...
随机推荐
- NativeXml实例训练时注意事项_1
NativeXml实例训练: 1)使用NativeXml操作xml文件时,需要将几个单元文件在Library中引用,配置好这个后面的就可自由训练.或按照自己想要的组合折腾. 2)运行程序调 ...
- 当小程序的flex布局遇到button时,justify-content不起作用的原因及解决方案
当小程序的flex布局遇到button时 发现justify-content不起作用,无论怎么设置都是space-around的效果. 经过排查,发现原因是小程序button中的默认样式中的margi ...
- Idea创建Scala的Maven项目
Idea版本(2018.1.5) Scala版本(2.11.0) Java版本(1.8.0_151) 创建Scala的Maven项目 Idea新建项目如图,输入GroupId和ArtifactId之后 ...
- LR字符串处理函数-lr_save_string
int lr_save_string( const char *param_value, const char *param_name) 指定字符串保存至参数 Action() { lr_save_s ...
- 一时技痒,撸了个动态线程池,源码放Github了
阐述背景 线程池在日常工作中用的还挺多,当需要异步,批量处理一些任务的时候我们会定义一个线程池来处理. 在使用线程池的过程中有一些问题,下面简单介绍下之前遇到的一些问题. 场景一:实现一些批量处理数据 ...
- mongodb 数据库 增删改查
mongodb 数据库 增删改查 增: // 引入express 模块 var express = require('express'); // 路由var router = expr ...
- 第一章:开始启程-你的第一行Android代码
Android 系统为开发者提供了什么? 四大组件 活动(Activity):界面 服务(Service):后台默默运行 广播接收器(Broadcast Receiver):接收.发送广播消息 内容提 ...
- Perl入门 - Perl方法的使用
1.定义一个方法 Perl使用sub定义方法. 语法: sub 方法名称{方法体} 2.调用一个方法 Perl直接使用方法名称调用方法. 调用方式有以下四种: 方法名称: &方法名称: 方法名 ...
- 2020/6/11 JavaScript高级程序设计 DOM
DOM(文档对象模型)是针对HTML和XML文档的一个API(应用程序接口).他描绘了一个层次化的节点树,允许开发人员添加.移除和修改页面的某一部分. 10.1 节点层次 DOM将任何HTML和XML ...
- SpringBoot--异常统一处理
先上代码,不捕获异常和手动捕获异常处理: @GetMapping("/error1") public String error1() { int i = 10 / 0; retur ...