Java之Java程序与虚拟机
Java为什么要在虚拟机中运行
- 简单的来说,Java作为一门高级程序语言,语法复杂,抽象度高,不能直接翻译为机器码在机器上运行,所以设计者就设计了虚拟机,通过编译器将Java程序转换成虚拟机所能识别的指令码,也就是Java字节码,Java字节码会被虚拟机翻译为可以被机器识别的机器码.这也实现了Java的跨平台
- 虚拟机的第二个好处就是带来了一个托管环境,托管环境能够代替我们处理代码中冗余并且容易出错的部分,比如自动内存管理,垃圾回收. 还有诸如数组越界、动态类型、安全权限等等动态监测.
Java如何在虚拟机中运行的
- 从虚拟机角度来看,执行Java代码首先需要将它编译而成的class文件加载到虚拟机中.加载后的Java类会被存放与方法区(Method Area)中,运行时,虚拟机执行方法区内的代码
Java虚拟机如何存储运行时的数据
Java虚拟机在内存中划分出堆和栈来存储运行时数据.并且将栈细分为面向Java方法的Java方法栈,面向本地方法的本地方法栈,以及存放各个线程执行位置的PC寄存器.
运行的过程中,每当调用一个方法,Java虚拟机会在当前线程的Java方法栈中生成一个栈帧,存放局部变量以及字节码操作数.这个栈帧大小提前计算好,而且Java虚拟机不要求栈帧在内存空间中连续分步.退出执行方法时,Java虚拟机会弹出当前线程的当前栈帧,并舍弃.
前面说到Java字节码会被虚拟机翻译成机器码,那是如何翻译的呢?有两种形式:第一种是解释执行,也就是逐条将字节码翻译成机器码并执行,优势是无需等待编译.第二种是即时编译(JIT),也就是将一个方法中包含的所有字节码编译成机器码后再执行,优势在于实际运行速度很快.而我们常用的HotSpot虚拟机默认采用混合模式,综合了解释执行和即时编译两者的优点,先解释执行字节码,而后将反复执行的热点代码,以方法为单位进行即时编译.
运行效率如何
前面说的极是编译就是用来提升性能以及峰值性能,它是建立在程序符合二八定律的假设上,也就是百分之二十的代码占据百分之八十的计算资源.
如何理解?对于占据大部分不常用的代码,无需耗费时间将其编译成机器码,而是采取解释执行的方式运行;另一方面,对于占据小部分的热点代码,将其编译器成机器码,提高运行速度.
HotSpot 内置了多个即时编译器:C1、C2 和 Graal。Graal 是
Java 10 正式引入的实验性即时编译器,InfoQ上有个介绍(http://www.infoq.com/cn/articles/Graal-Java-JIT-Compiler?utm_source=articles_about_java&utm_medium=link&utm_campaign=java),有兴趣的可以了解下.
C1 又叫做 Client 编译器,面向的是对启动性能有要求的客户端 GUI 程序,采用的优化手段相对简单,因此编译时间较短。
C2 又叫做 Server 编译器,面向的是对峰值性能有要求的服务器端程序,采用的优化手段相对复杂,因此编译时间较长,但同时生成代码的执行效率较高。
Java7开始,HotSpot默认采取分层编译:热点方法首先被C1编译,而后热点方法中的热点会进一步被C2编译.
总结
之所以要在虚拟机中运行,是因为它提供了可移植性。一旦 Java 代码被编译为 Java 字节码,便可以在不同平台上的 Java 虚拟机实现上运行。此外,虚拟机还提供了一个代码托管的环境,
代替我们处理部分冗长而且容易出错的事务,例如内存管理。
Java 虚拟机将运行时内存区域划分为五个部分,分别为方法区、堆、PC 寄存器、Java 方法栈和本地方法栈。Java 程序编译而成的 class 文件,需要先加载至方法区中,方能在 Java 虚拟机
中运行。
为了提高运行效率,标准 JDK 中的 HotSpot 虚拟机采用的是一种混合执行的策略。
它会解释执行 Java 字节码,然后会将其中反复执行的热点代码,以方法为单位进行即时编译,翻译成机器码后直接运行在底层硬件之上。
HotSpot 装载了多个不同的即时编译器,以便在编译时间和生成代码的执行效率之间做取舍。
Java之Java程序与虚拟机的更多相关文章
- 简单java在线测评程序
简单java程序在线测评程序 一.前言 大家过年好!今年的第一篇博客啊!家里没有网,到处蹭无线!日子过得真纠结!因为毕设的需求,简单写了一个java程序在线测评程序,当然也可以在本地测试. 二.思路 ...
- Java泛型解析(03):虚拟机运行泛型代码
Java泛型解析(03):虚拟机运行泛型代码 Java虚拟机是不存在泛型类型对象的,全部的对象都属于普通类,甚至在泛型实现的早起版本号中,可以将使用泛型的程序编译为在1.0虚拟机上可以执行的 ...
- Java 9 揭秘(16. 虚拟机栈遍历)
Tips 做一个终身学习的人. 在本章中,主要介绍以下内容: 什么是虚拟机栈(JVM Stack)和栈帧(Stack Frame) 如何在JDK 9之前遍历一个线程的栈 在JDK 9中如何使用Stac ...
- JAVA 文件编译执行与虚拟机(JVM)简单介绍
详见:http://blog.yemou.net/article/query/info/tytfjhfascvhzxcytpo3 java程序的内存分配 JAVA 文件编译执行与虚拟机(JVM)介绍 ...
- 【转】java线上程序排错经验2 - 线程堆栈分析
前言 在线上的程序中,我们可能经常会碰到程序卡死或者执行很慢的情况,这时候我们希望知道是代码哪里的问题,我们或许迫切希望得到代码运行到哪里了,是哪一步很慢,是否是进入了死循环,或者是否哪一段代码有问题 ...
- Java内存管理-程序运行过程(一)
勿在流沙住高台,出来混迟早要还的. 做一个积极的人 编码.改bug.提升自己 我有一个乐园,面向编程,春暖花开! 相信在做Java开发的伙伴一定知道 JVM(Java Virtual Machine( ...
- JAVA面试-java虚拟机
1.JVM简析: 作为一名Java使用者,掌握JVM的体系结构也是很有必要的. 说起Java,我们首先想到的是Java编程语言,然而事实上,Java是一种技术,它由四方面组成:Ja ...
- 深入理解Java内存模型中的虚拟机栈
深入理解Java内存模型中的虚拟机栈 Java虚拟机在执行Java程序的过程中会把它所管理的内存划分为若干个不同的数据区域,这些区域都会有各自的用途,以及创建和销毁的时间,有的区域会随着虚拟机进程的启 ...
- 在IntelliJ IDEA中创建和运行java/scala/spark程序
本文将分两部分来介绍如何在IntelliJ IDEA中运行Java/Scala/Spark程序: 基本概念介绍 在IntelliJ IDEA中创建和运行java/scala/spark程序 基本概念介 ...
随机推荐
- 笔记:《机器学习训练秘籍》——吴恩达deeplearningai微信公众号推送文章
说明 该文为笔者在微信公众号:吴恩达deeplearningai 所推送<机器学习训练秘籍>系列文章的学习笔记,公众号二维码如下,1到15课课程链接点这里 该系列文章主要是吴恩达先生在机器 ...
- jQuery的基本使用
一.jQuery简介 jQuery是一个快速.简洁的JavaScript框架,它封装了JavaScript常用的功能代码,提供一种简便的JavaScript设计模式,优化HTML文档操作.事件处理.动 ...
- basename命令详解
基础命令学习目录首页 摘要:前言bashname命令用于获取路径中的文件名或路径名(获取的时候叶子节点的元素内容)常见用法举例basenamepath获取末尾的文件名或路径名1:[aliyunzixu ...
- dumpe2fs命令详解
基础命令学习目录首页 dumpe2fs 显示ext2.ext3.ext4文件系统的超级快和块组信息.此命令的适用范围:RedHat.RHEL.Ubuntu.CentOS.SUSE.openSUSE ...
- Hadoop错误码速查
经常遇到的exception是:PipeMapRed.waitOutputThreads(): subprocess failed with code N "OS error code 1: ...
- Daily Scrum (2015/11/4)
因为距离部署的时间临近,而之前我们的进度偏慢.这天晚上我们大多数成员几乎所有时间都用在了这个项目上,成果还算令人满意. 成员 今日任务 时间 明日任务 符美潇 1.修复了一个BUG,此BUG会导致所爬 ...
- Daily Scrum (2015/10/28)
昨天DEV们完成了一部分代码风格的修整.今晚在与其他组进行交流时我们发现我们的代码是需要在服务器上运行的,而且服务器是需要配置的,而且据说需要花一些时间.所以在编写代码之前PM提出我们应该先把服务器搭 ...
- 20162325 金立清 S2 W5 C14
20162325 2017-2018-2 <程序设计与数据结构>第5周学习总结 关键内容摘要 集合是收集并组织其他对象的对象 集合中的元素一般由加入集合的次序或元素之间某些固有的关系而组织 ...
- linux 常用命令-ps命令
ps(process status):进程状态相关命令 1.
- 对于Redis的了解
Redis :高性能的key-value数据库,支持存储的value类型包括字符串.链表.集合.有序集合.哈希类型. redis使用两种文件格式:全量数据和增量请求. 全量数据格式是将内存中的数据写入 ...