Java为什么要在虚拟机中运行

  1. 简单的来说,Java作为一门高级程序语言,语法复杂,抽象度高,不能直接翻译为机器码在机器上运行,所以设计者就设计了虚拟机,通过编译器将Java程序转换成虚拟机所能识别的指令码,也就是Java字节码,Java字节码会被虚拟机翻译为可以被机器识别的机器码.这也实现了Java的跨平台
  2. 虚拟机的第二个好处就是带来了一个托管环境,托管环境能够代替我们处理代码中冗余并且容易出错的部分,比如自动内存管理,垃圾回收. 还有诸如数组越界、动态类型、安全权限等等动态监测.

Java如何在虚拟机中运行的

  1. 从虚拟机角度来看,执行Java代码首先需要将它编译而成的class文件加载到虚拟机中.加载后的Java类会被存放与方法区(Method Area)中,运行时,虚拟机执行方法区内的代码

Java虚拟机如何存储运行时的数据

Java虚拟机在内存中划分出堆和栈来存储运行时数据.并且将栈细分为面向Java方法的Java方法栈,面向本地方法的本地方法栈,以及存放各个线程执行位置的PC寄存器.

运行的过程中,每当调用一个方法,Java虚拟机会在当前线程的Java方法栈中生成一个栈帧,存放局部变量以及字节码操作数.这个栈帧大小提前计算好,而且Java虚拟机不要求栈帧在内存空间中连续分步.退出执行方法时,Java虚拟机会弹出当前线程的当前栈帧,并舍弃.

前面说到Java字节码会被虚拟机翻译成机器码,那是如何翻译的呢?有两种形式:第一种是解释执行,也就是逐条将字节码翻译成机器码并执行,优势是无需等待编译.第二种是即时编译(JIT),也就是将一个方法中包含的所有字节码编译成机器码后再执行,优势在于实际运行速度很快.而我们常用的HotSpot虚拟机默认采用混合模式,综合了解释执行和即时编译两者的优点,先解释执行字节码,而后将反复执行的热点代码,以方法为单位进行即时编译.

运行效率如何

前面说的极是编译就是用来提升性能以及峰值性能,它是建立在程序符合二八定律的假设上,也就是百分之二十的代码占据百分之八十的计算资源.

如何理解?对于占据大部分不常用的代码,无需耗费时间将其编译成机器码,而是采取解释执行的方式运行;另一方面,对于占据小部分的热点代码,将其编译器成机器码,提高运行速度.

HotSpot 内置了多个即时编译器:C1、C2 和 Graal。Graal 是

C1 又叫做 Client 编译器,面向的是对启动性能有要求的客户端 GUI 程序,采用的优化手段相对简单,因此编译时间较短。

C2 又叫做 Server 编译器,面向的是对峰值性能有要求的服务器端程序,采用的优化手段相对复杂,因此编译时间较长,但同时生成代码的执行效率较高。

Java7开始,HotSpot默认采取分层编译:热点方法首先被C1编译,而后热点方法中的热点会进一步被C2编译.

总结

之所以要在虚拟机中运行,是因为它提供了可移植性。一旦 Java 代码被编译为 Java 字节码,便可以在不同平台上的 Java 虚拟机实现上运行。此外,虚拟机还提供了一个代码托管的环境,
代替我们处理部分冗长而且容易出错的事务,例如内存管理。

Java 虚拟机将运行时内存区域划分为五个部分,分别为方法区、堆、PC 寄存器、Java 方法栈和本地方法栈。Java 程序编译而成的 class 文件,需要先加载至方法区中,方能在 Java 虚拟机
中运行。

为了提高运行效率,标准 JDK 中的 HotSpot 虚拟机采用的是一种混合执行的策略。

它会解释执行 Java 字节码,然后会将其中反复执行的热点代码,以方法为单位进行即时编译,翻译成机器码后直接运行在底层硬件之上。

HotSpot 装载了多个不同的即时编译器,以便在编译时间和生成代码的执行效率之间做取舍。

原文地址:https://www.cnblogs.com/YWJAVA7010/p/9392327.html

时间: 2024-11-02 22:01:34

Java为什么要在虚拟机中运行的相关文章

轻易解决VMware 虚拟机中被提示“请不要在虚拟机中运行此程序“

决 VMware 虚拟机 中被提示 "请不要在虚拟机中运行此程序"或者"Themida Sorry, this application cannot run under a Virtual Machine"方法 自己发现问题,解决问题后,觉得应该分享给大家.用记事本打开 VMX 文件 类似 Windows XP Professional.vmx ,在文本末尾加入一行 monitor_control.restrict_backdoor = TRUE 保存文件 现在启动

Unity3d发布apk文件并在Android虚拟机中运行的操作流程

总的流程分为以下6个步骤: 1.安装java_jdk 2.配置java环境变量 3.更新android的sdk 4.从Unity3d中发布出apk文件 5.创建android虚拟机并运行 6.将apk文件安装到android虚拟机中 (为方便新手,在下面对每个步骤的具体操作及可能遇到的问题详细提一下) 1.安装java_jdk 官网(www.java.com),免费,我安装的文件的名字是jdk-7u10-windows-i586.exe,版本有新旧,你下载到的版本号可能与我不同,不碍事: 2.配

java项目打包在shell中运行

在工作中,有时处需要处理些数据,用java比较方面,比如hbase,但是需要在shell中执行,这样的话,额外的包打进去就比较费劲了,用Maven进行打包非常方便. 首先在项目中pop.xml 写入需要的jar包,以及需要运行的类,如下所示, <dependency> <groupId>org.apache.hbase</groupId> <artifactId>hbase</artifactId> <version>0.94.5&l

虚拟机中的运行时栈帧

每个人都知道,各种各样的动画视频,都是由一帧一帧图片连续切换结果的结果而产生的,其实虚拟机的运行和动画也类似,每个在虚拟机中运行的程序也是由许多的帧的切换产生的结果,只是这些帧里面存放的是方法的局部变量,操作数栈,动态链接,方法返回地址和一些额外的附加信息组成,在虚拟机中包含这些信息的帧称为"栈帧",每个方法的执行,在虚拟机中都是对应的栈帧在虚拟机栈中的入栈到出栈的过程.其中比较重要的一点时,如果虚拟机中同时有多个线程在执行,那么各个线程的栈帧都是相互独立,互不侵犯的,所以这也实现了局

在win10环境下安装虚拟机并运行win7系统步骤

1.需要的有: 原生windows10 系统 [32/64] 任意一款windows 7系统 [32/64] VMware Workstation Pro 虚拟机 vmware workstation 12序列号: 5a02h-au243-tzj49-gtc7k-3c61n 2.步骤如下: 下载安装运行vmware workstation 虚拟机 单击创建新的虚拟机 进入新建向导界面 选择自定义 下一步 直接下一步就可以 在这个界面,选择您下载好的win7-ISO格式压缩包,必须是ISO格式的,

erlang虚拟机代码运行原理

erlang是开源的,非常多人都研究过源码.可是.从erlang代码到c代码.这是个不小的跨度.并且代码也比較复杂. 所以这里,我利用一些时间,整理下erlang代码的运行过程.从erlang代码编译过程,到代码运行过程做解说.然后重点讲下虚拟机运行代码的原理.将本篇文章.献给全部喜欢erlang的人. erlang代码编译过程 erlang对开发人员是友好的.从erlang程序文件编译成能被erlang虚拟机识别的beam文件,在这个编译过程还对开发人员暴露中间代码.借助这个中间代码,我们就能

深入理解Java虚拟机:运行时数据区域

Java虚拟机在执行Java程序的过程中会把它所管理的内存划分为若干个不同的数据区域.这些区域都有各自的用途,以及创建和销毁的时间,有的区域随着虚拟机进程的启动而存在,有些区域则依赖用户线程的启动和结束而建立和销毁.根据<Java虚拟机规范(Java SE 7版)>的规定,Java虚拟机所管理的内存将会包括以下几个运行时数据区域. 程序计数器 程序计数器(Program Counter Register)是一块较小的内存空间,它可以看作是当前线程所执行的字节码的行号指示器.在虚拟机的概念模型里

(转)在Docker中运行Java:为了防止失败,你需要知道这些

转自:https://mp.weixin.qq.com/s?__biz=MzA5OTAyNzQ2OA==&mid=2649693848&idx=1&sn=4e9ef7e2a9d41b39985899b6ad146298&chksm=889321fbbfe4a8ed58d09e6bcf2f9c2603859c331489c0a8a56b8050e601438415b1398fc1f6&mpshare=1&scene=1&srcid=0419cxIPfJ

聊聊JAVA虚拟机中的垃圾收集器

前言 JAVA虚拟机的垃圾收集器是虚拟机内存的清道夫,它的存在让JAVA开发人员能将更多精力投入到业务研发上.了解垃圾收集器,并利用好这个工具,能更好的保障服务稳定性.这篇文章通过分析JAVA虚拟机内存模型,介绍垃圾收集器常用算法和收集器类别,使得垃圾收集器的配置和使用变得不再遥不可及. JAVA虚拟机内存模型 JAVA虚拟机内存可以划分为:虚拟机栈.本地方法栈.JAVA堆内存.方法区(包含运行时常量池).程序计数器.直接内存. 虚拟机栈 虚拟机栈是线程私有的,生命周期跟线程相同.也就是说一个线