01java代码是怎么运行的

yuepenglei      2022-04-25     494

关键词:

Java代码运行的方式

1:在开发工具中运行
2:双击 jar 文件运行
3:在命令行中运行
4:在网页中运行

上述运行方式都离不开 JRE,也就是 Java 运行时环境。实际上 JRE 仅包含运行 Java 程序的必须组件,包括 Java 虚拟机以及 Java 核心类库等。Java 程序员经常接触到的 JDK 同样包含了 JRE,并且还附带了一系列开发和诊断工具。

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

Java 是一门高级程序语言,语法复杂,抽象程度高,因此直接在硬件上运行并不现实。所以,在 Java 程序运行之前,需要对其进行转换。

设计一个面向 Java 语言的特性的虚拟机,并通过编译器将 Java 程序转换成该虚拟机所能识别的指令程序,也叫 Java 字节码。之所以叫做字节码,是因为 Java 字节码指令的操作码被固定为一个字节。

使用虚拟机的好处

Java 虚拟机也可以由硬件直接实现,但是更为常见的是基于软件实现。

如果一个 Java 程序被转换成 Java 字节码,那么他便可以在不同平台上的 Java 虚拟机实现里运行。这就是通常所说的:一次编译,到处运行。

虚拟机的另一个好处就是它提供了一个托管环境。这个托管环境代替我们处理一些代码中冗长而且容易出错的代码。最明显的使用就是自动内存管理和垃圾回收。托管环境还提供了诸如数组越界,动态类型,安全权限等等动态监测。

Java 虚拟机如何运行 Java 字节码

下面以标准 JDK 中的 HotSpot 虚拟机为例,从虚拟机以及底层硬件两个角度进行分析。

从虚拟机的视角来看,首先将 Java 代码编译成 class 文件加载到 Java 虚拟机中。加载后的 Java 类会被存放于方法区,实际运行时,虚拟机会执行方法区的代码。

Java 虚拟机在内存中划分出堆和栈来存储运行时的数据。对于栈, Java 虚拟机会把其细分为面向 Java 方法的 Java 方法栈,面向本地方法(用 C++ 写的 native 方法)的本地方法栈,以及存放各个线程执行位置的 PC 寄存器。

技术分享图片

在虚拟机运行过程中,每当调用进入一个 Java 方法, Java 虚拟机会在当前线程的 Java 方法栈中生成一个栈帧,用以存放局部变量以及字节码的操作数。

当退出当前执行的方法时,不管是正常返回还是异常返回,Java 虚拟机均会弹出当前线程的当前栈帧,将之舍弃。

从硬件的视角来看,Java 字节码无法直接执行,因此 Java 虚拟机需要将字节码翻译成机器码。

翻译的形式有两种,一种是解释执行,即逐条将字节码翻译成机器码执行;一种是即时编译,即将一个方法中包含的所有字节码编译成机器码后再执行。

技术分享图片

解释执行的优势在于无需等待编译,及时编译的优势在于实际运行速度会更快。HotSpot 默认采用混合模式,综合了解释执行和即时编译两者的优点。它会先解释执行字节码,而后将其中反复执行的热点代码,以方法为单位进行即时编译。

Java 虚拟机的运行效率

HotSpot 采用了多种技术来提升启动性能以及峰值性能,即时编译就是其中最重要的技术之一。

为了满足不同用户场景的需要,HotSpot 内置了多个即时编译器:C1,C2 和 Graal。Graal 是 Java 10 正式引入的实验性即时编译器,后续再总结。引入多个即时编译器,是为了在编译时间和生成代码的执行效率之间进行取舍。

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

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

从 Java 7 开始,HotSpot 默认次用分层编译的方式:热点方法首先会被 C1 编译,而后热点方法中的热点会进一步被 C2 编译。

为了不干扰应用正常的运行,HotSpot 的即时编译是放在额外的编译线程中进行的。HotSpot 会根据 CPU 的数量设置编译线程的数目,并且按 1:2 的比例分配给 C1 和 C2 编译器。

问答

Q:对于发布一次就长时间运行的程序,为什么不选择直接将 Java 字节码编译成机器码

事实上 JVM 却是有考虑做 AOT 的这种事情。AOT 能够在线下将 Java 字节码编译成机器码,主要用来解决启动性能不好的问题。其实线下编译和即时编译都一样,至多一两个小时后该编译的都已经编译完成了。另外,即时编译器因为有程序运行时信息,优化效果更好,也就是说峰值性能更好。

Q:如何区分热点代码和非热点代码

关于热点代码的统计有两种算法:一种是基于采样的热点探测,一种是基于计数器的热点探测。基于计数器的热点探测又有两个计数器:一种是方法调用计数器,一种是回边计数器,他们在 C1 和 C2 中有不同的阈值。默认的分层编译应该是达到两千调用 C1,达到一万五调用 C2。一般采用的都是基于计数器的热点探测。

Q:对于 JVM 的及时编译,当方法体中有很多 if,else if 这样的判断,如何编译

JVM 有两种编译方式,一种是对整个方法进行编译,一种是对热循环进行编译。无论哪种,都要比 if else 的粒度大。

总结

本文创作灵感来源于 极客时间 郑雨迪老师的《深入拆解 Java 虚拟机》课程,通过课后反思以及借鉴各位学友的发言总结,现整理出自己的知识架构,以便日后温故知新,查漏补缺。

关注本人公众号,第一时间获取最新文章发布,每日更新一篇技术文章。

技术分享图片




java程序员必备基础:java代码是怎么运行的?

前言作为一名Java程序员,我们需要知道Java代码是怎么运行的。最近复习了深入理解Java虚拟机,做了一下总结,希望对大家有帮助,如果有不正确的地方,欢迎提出,感激不尽。java代码运行主要流程本文主要讲解流程如下:java... 查看详情

java源代码怎么运行

在这有个代码怎么样运行这个程序.java文件的话,非项目那种单篇幅的源代码需要先进行编译,生成.class文件可以在命令控制台下用java文件名进行运行,编译java文件需要javac.exe程序应该是jdk中的工具,所以你需要下载jdk并配置... 查看详情

java程序是怎么运行的?(代码片段)

...换Java程序是怎么运行的?概括来说,写好的Java源代码文件经过Java编译器编译成字节码文件后,通过类加载器加载到内存中,才能被实例化,然后到Java虚拟机中解释执行,最后通过操作系 查看详情

java代码是怎么运行的

  Java代码执行步骤     编译  Java文件通过JVM的编译器编译成字节码文件,有了字节码,JVM的类加载器就开始加载字节码文件。        解释器  解释器会将字节码转换成汇编指令,然... 查看详情

java是怎么跨平台运行的

...va虚拟机能跨平台。   因为Java程序编译之后的代码不是能被硬件系统直接运行的代码,而是一种“中间码”——字节码。然后不同的硬件平台上安装有不同的Java虚拟机(JVM),由虚拟机(JVM)来把字节码再“翻译”成所对... 查看详情

java程序的运行机制是怎么样的?

Java程序的运行机制可以分为以下几个步骤:编写Java源代码:首先,程序员需要使用Java编程语言编写源代码。Java源代码是以.java为扩展名的文本文件,包含了Java程序的逻辑和功能。编译Java源代码:Java源代码需要通过Java编译器... 查看详情

java编写代码两个放到同个包中一起运行,怎么操作

参考技术A两个类放到包里面后,选择一个类设为启动类或者再写一个启动类,然后在启动类里面调用其它类就好了 参考技术B将两个类文件A、B发入一个包中(创建指定的包bag),类文件A实现输出F5,y-10,类文件B实现输出张三的姓... 查看详情

java基础01-开发环境&数据类型(代码片段)

Java开发环境JVM(JavaVirtualMachine)在需要运行Java应用程序的操作系统上,安装一个与操作系统对应的JVMJRE(JavaRuntimeEnvironment)是Java程序运行时的环境,包含JVM和运行时需要的核心类库JDK(JavaDevelopmentKit... 查看详情

怎么在电脑上运行java源程序代码

谁给一个Java游戏源程序的代码,小游戏,还有请问怎么把Java源程序代码转变成Java游戏运行?我是新手等不及了手上有几个源程序代码就是不会运行,最好详细一点第一,环境变量没有问题,但是代码用java的方式运行不了。首... 查看详情

java代码写好后怎么运行?

...件非常自豪的事情,那么你知道应该如何才能运行Java代码吗?今天小千就来给大家介绍一下。Java代码运行方法1.首先需要确保你的电脑正确安装了Java环境并且环境变量都配置完成,之后我们在电脑上编辑好自己的Java... 查看详情

通俗易懂!我们写的java代码到底是如何运行的?(代码片段)

...天,庆哥带大家来看一个问题,就是我们写的Java代码到底是如何运行的?一般涉及到这样的话题,有些人肯定会觉得,肯定又是底层,又是源码的࿰ 查看详情

通俗易懂!我们写的java代码到底是如何运行的?(代码片段)

...天,庆哥带大家来看一个问题,就是我们写的Java代码到底是如何运行的?一般涉及到这样的话题,有些人肯定会觉得,肯定又是底层,又是源码的࿰ 查看详情

java怎么识别当前运行环境是docker

...a8的极小的框架。Spark使用Maven作为构建工具。回到顶部源代码和配置文件在这个例子中你要增加三个文件:Maven的配置文件:pom.xml一个Java类:Hello.java一个Dockerfile本回答被提问者采纳 查看详情

在Java中运行代码x秒?

】在Java中运行代码x秒?【英文标题】:RuncodeforxsecondsinJava?【发布时间】:2011-01-0300:01:50【问题描述】:我想编写一个javawhile循环,它将迭代15秒。我认为这样做的一种方法是存储当前系统时间+15秒,然后将其与while循环签名中... 查看详情

java01-接口(dao模式代码阅读及应用)

目录DAO模式是接口的一个典型应用。阅读附件中的参考代码:1.StudenDaoListImpl.java与StudentDaoArrayImpl.java有何不同?2.StudentDao.java文件是干什么用的?为什么里面什么实现代码都没有?3.使用搜索引擎搜索“JavaDAO”,选出几句你能看懂的、... 查看详情

jvm_01内存结构篇(代码片段)

JVM(JavaVirtualMachine)一、前言1、什么是JVM?1、定义:JavaVirtualMachine,Java程序的运行环境(Java二进制字节码的运行环境)。2、好处:一次编译,处处执行自动的内存管理,垃圾回收机制数... 查看详情

读《程序是怎么跑起来的》第七章有感

...BSD是一种Unix操作系统,通过各个环境中编译Ports中公开的代码,就可以执行有此可以生成的本地代码了,而模拟器是指在Macintosh上提供虚拟的Windows环境,只要分别为各个环境安装专用Java虚拟机,同样的字节代码就能在各个环境... 查看详情

java01java概述(代码片段)

学习教程:b站韩顺平一、JVMJVM是一个虚拟计算机,拥有指令集并使用不同的存储区域,负责执行指令,管理数据,内存,寄存器,包含在JDK中对于不同平台,由不同虚拟机,Java虚拟机制屏蔽了... 查看详情