Java详解JVM工作原理和流程

Java虚拟机启动过程解析 一、序言 当我们在编写Java应用的时候,很少会注意Java程序是如何被运行的,如何被操作系统管理和调度的。带着好奇心,探索一下Java虚拟机启动过程。 1、素材准备 从Java源代码、Java字节码、Java虚拟机、操作系统四个角度分解启动过程。 public class HelloWorld { public static void main(String[] args) { System.out.println("HelloWorld!"); ... 阅读详情

作为一名Java使用者,掌握JVM的体系结构也是必须的。
说起Java,人们首先想到的是Java编程语言,然而事实上,Java是一种技术,它由四方面组成:Java编程语言、Java类文件格式、Java虚拟机和Java应用程序接口(Java API)。它们的关系如下图所示:

运行期环境代表着Java平台,开发人员编写Java代码(.java文件),然后将之编译成字节码(.class文件),再然后字节码被装入内存,一旦字节码进入虚拟机,它就会被解释器解释执行,或者是被即时代码发生器有选择的转换成机器码执行。

Java平台由Java虚拟机和Java应用程序接口搭建,Java语言则是进入这个平台的通道,用Java语言编写并编译的程序可以运行在这个平台上。这个平台的结构如下图所示:

在Java平台的结构中, 可以看出,Java虚拟机(JVM) 处在核心的位置,是程序与底层操作系统和硬件无关的关键。它的下方是移植接口,移植接口由两部分组成:适配器和Java操作系统, 其中依赖于平台的部分称为适配器;JVM 通过移植接口在具体的平台和操作系统上实现;在JVM 的上方是Java的基本类库和扩展类库以及它们的API, 利用Java API编写的应用程序(application) 和小程序(Java applet) 可以在任何Java平台上运行而无需考虑底层平台, 就是因为有Java虚拟机(JVM)实现了程序与操作系统的分离,从而实现了Java 的平台无关性。

JVM在它的生存周期中有一个明确的任务,那就是运行Java程序,因此当Java程序启动的时候,就产生JVM的一个实例;当程序运行结束的时候,该实例也跟着消失了。下面我们从JVM的体系结构和它的运行过程这两个方面来对它进行比较深入的研究。

1、Java虚拟机的体系结构

·每个JVM都有两种机制:

①类装载子系统:装载具有适合名称的类或接口

②执行引擎:负责执行包含在已装载的类或接口中的指令 

·每个JVM都包含:

方法区、Java堆、Java栈、本地方法栈、指令计数器及其他隐含寄存器

对于JVM的学习,在我看来这么几个部分最重要:

Java代码编译和执行的整个过程

JVM内存管理及垃圾回收机制

下面分别对这几部分进行说明:

2、Java代码编译和执行的整个过程

也正如前面所说,Java代码的编译和执行的整个过程大概是:开发人员编写Java代码(.java文件),然后将之编译成字节码(.class文件),再然后字节码被装入内存,一旦字节码进入虚拟机,它就会被解释器解释执行,或者是被即时代码发生器有选择的转换成机器码执行。

(1)Java代码编译是由Java源码编译器来完成,也就是Java代码到JVM字节码(.class文件)的过程。 流程图如下所示: 

 

Java代码编译和执行的整个过程包含了以下三个重要的机制:

·Java源码编译机制

·类加载机制

·类执行机制

 

(1)Java源码编译机制

Java 源码编译由以下三个过程组成:

①分析和输入到符号表

②注解处理

③语义分析和生成class文件

流程图如下所示:

 

最后生成的class文件由以下部分组成:

①结构信息:包括class文件格式版本号及各部分的数量与大小的信息

②元数据:对应于Java源码中声明与常量的信息。包含类/继承的超类/实现的接口的声明信息、域与方法声明信息和常量池

③方法信息:对应Java源码中语句和表达式对应的信息。包含字节码、异常处理器表、求值栈与局部变量区大小、求值栈的类型记录、调试符号信息

(2)类加载机制
JVM的类加载是通过ClassLoader及其子类来完成的,类的层次关系和加载顺序可以由下图来描述:

 

①Bootstrap ClassLoader

负责加载$JAVA_HOME中jre/lib/rt.jar里所有的class,由C++实现,不是ClassLoader子类

②Extension ClassLoader

负责加载java平台中扩展功能的一些jar包,包括$JAVA_HOME中jre/lib/*.jar或-Djava.ext.dirs指定目录下的jar包

③App ClassLoader

负责记载classpath中指定的jar包及目录中class

④Custom ClassLoader

属于应用程序根据自身需要自定义的ClassLoader,如tomcat、jboss都会根据j2ee规范自行实现ClassLoader

 

加载过程中会先检查类是否被已加载,检查顺序是自底向上,从Custom ClassLoader到BootStrap ClassLoader逐层检查,只要某个classloader已加载就视为已加载此类,保证此类只所有ClassLoader加载一次。而加载的顺序是自顶向下,也就是由上层来逐层尝试加载此类。

(3)类执行机制

JVM是基于堆栈的虚拟机。JVM为每个新创建的线程都分配一个堆栈.也就是说,对于一个Java程序来说,它的运行就是通过对堆栈的操作来完成的。堆栈以帧为单位保存线程的状态。JVM对堆栈只进行两种操作:以帧为单位的压栈和出栈操作。

JVM执行class字节码,线程创建后,都会产生程序计数器(PC)和栈(Stack),程序计数器存放下一条要执行的指令在方法内的偏移量,栈中存放一个个栈帧,每个栈帧对应着每个方法的每次调用,而栈帧又是有局部变量区和操作数栈两部分组成,局部变量区用于存放方法中的局部变量和参数,操作数栈中用于存放方法执行过程中产生的中间结果。栈的结构如下图所示:

3、JVM内存管理及垃圾回收机制

JVM内存结构分为:方法区(method),栈内存(stack),堆内存(heap),本地方法栈(java中的jni调用),结构图如下所示:

(1)堆内存(heap)

所有通过new创建的对象的内存都在堆中分配,其大小可以通过-Xmx和-Xms来控制。 
操作系统有一个记录空闲内存地址的链表,当系统收到程序的申请时,会遍历该链表,寻找第一个空间大于所申请空间的堆结点,然后将该结点从空闲结点链表中删除,并将该结点的空间分配给程序,另外,对于大多数系统,会在这块内存空间中的首地址处记录本次分配的大小,这样代码中的delete语句才能正确的释放本内存空间。但由于找到的堆结点的大小不一定正好等于申请的大小,系统会自动的将多余的那部分重新放入空闲链表中。这时由new分配的内存,一般速度比较慢,而且容易产生内存碎片,不过用起来最方便。另外,在WINDOWS下,最好的方式是用VirtualAlloc分配内存,它不是在堆,也不是在栈,而是直接在进程的地址空间中保留一块内存,虽然这种方法用起来最不方便,但是速度快,也是最灵活的。堆内存是向高地址扩展的数据结构,是不连续的内存区域。由于系统是用链表来存储的空闲内存地址的,自然是不连续的,而链表的遍历方向是由低地址向高地址。堆的大小受限于计算机系统中有效的虚拟内存。由此可见,堆获得的空间比较灵活,也比较大。

(2)栈内存(stack)

在Windows下, 栈是向低地址扩展的数据结构,是一块连续的内存区域。这句话的意思是栈顶的地址和栈的最大容量是系统预先规定好的,在WINDOWS下,栈的大小是固定的(是一个编译时就确定的常数),如果申请的空间超过栈的剩余空间时,将提示overflow。因此,能从栈获得的空间较小。只要栈的剩余空间大于所申请空间,系统将为程序提供内存,否则将报异常提示栈溢出。 由系统自动分配,速度较快。但程序员是无法控制的。

堆内存与栈内存需要说明:

基础数据类型直接在栈空间分配,方法的形式参数,直接在栈空间分配,当方法调用完成后从栈空间回收。引用数据类型,需要用new来创建,既在栈空间分配一个地址空间,又在堆空间分配对象的类变量 。方法的引用参数,在栈空间分配一个地址空间,并指向堆空间的对象区,当方法调用完成后从栈空间回收。局部变量new出来时,在栈空间和堆空间中分配空间,当局部变量生命周期结束后,栈空间立刻被回收,堆空间区域等待GC回收。方法调用时传入的literal参数,先在栈空间分配,在方法调用完成后从栈空间收回。字符串常量、static在DATA区域分配,this在堆空间分配。数组既在栈空间分配数组名称,又在堆空间分配数组实际的大小。

如:

(3)本地方法栈(java中的jni调用)

用于支持native方法的执行,存储了每个native方法调用的状态。对于本地方法接口,实现JVM并不要求一定要有它的支持,甚至可以完全没有。Sun公司实现Java本地接口(JNI)是出于可移植性的考虑,当然我们也可以设计出其它的本地接口来代替Sun公司的JNI。但是这些设计与实现是比较复杂的事情,需要确保垃圾回收器不会将那些正在被本地方法调用的对象释放掉。

(4)方法区(method)

它保存方法代码(编译后的java代码)和符号表。存放了要加载的类信息、静态变量、final类型的常量、属性和方法信息。JVM用持久代(Permanet Generation)来存放方法区,可通过-XX:PermSize和-XX:MaxPermSize来指定最小值和最大值。

垃圾回收机制

堆里聚集了所有由应用程序创建的对象,JVM也有对应的指令比如 new, newarray, anewarray和multianewarray,然并没有向 C++ 的 delete,free 等释放空间的指令,Java的所有释放都由 GC 来做,GC除了做回收内存之外,另外一个重要的工作就是内存的压缩,这个在其他的语言中也有类似的实现,相比 C++ 不仅好用,而且增加了安全性,当然她也有弊端,比如性能这个大问题。

 

4、Java虚拟机的运行过程示例

上面对虚拟机的各个部分进行了比较详细的说明,下面通过一个具体的例子来分析它的运行过程。

虚拟机通过调用某个指定类的方法main启动,传递给main一个字符串数组参数,使指定的类被装载,同时链接该类所使用的其它的类型,并且初始化它们。例如对于程序:

编译后在命令行模式下键入: java HelloApp run virtual machine 

将通过调用HelloApp的方法main来启动java虚拟机,传递给main一个包含三个字符串"run"、"virtual"、"machine"的数组。现在我们略述虚拟机在执行HelloApp时可能采取的步骤。

开始试图执行类HelloApp的main方法,发现该类并没有被装载,也就是说虚拟机当前不包含该类的二进制代表,于是虚拟机使用ClassLoader试图寻找这样的二进制代表。如果这个进程失败,则抛出一个异常。类被装载后同时在main方法被调用之前,必须对类HelloApp与其它类型进行链接然后初始化。链接包含三个阶段:检验,准备和解析。检验检查被装载的主类的符号和语义,准备则创建类或接口的静态域以及把这些域初始化为标准的默认值,解析负责检查主类对其它类或接口的符号引用,在这一步它是可选的。类的初始化是对类中声明的静态初始化函数和静态域的初始化构造方法的执行。一个类在初始化之前它的父类必须被初始化。整个过程如下:

 本文转自:http://blog.youkuaiyun.com/优快云_980979768/article/details/47281037?locationNum=7&fps=1

在URP中正确写入Sprite深度以使用DOF 我准备在文字冒险中加入景深的效果,但是因为unity内置shader的缘故,sprite是不会写入深度的,而如果要使用PostProcessing的DOF效果的话,是必须要将半透明物体的深度正确写入Depth Buffer的,这篇消耗了我大量精力的文章就是要介绍正确写入的方法。 其实,如果只是要在2D游戏中实现类似于景深的效果,不写入深度其实也是可以的,我找到的有两种方案:一种是实时对Sprite进行模糊计算;二是直接使用离线预模糊的图片,根据强度进行混合。 离线预模糊 虽然这两种方法都可以比较简 阅读详情

相关推荐

SquareLine Studio汉化版安装激活全攻略:LVGL嵌入式UI设计从入门到出代码

嵌入式GUI开发中,LVGL作为轻量级开源图形库,广泛应用于STM32、ESP32等MCU平台。可视化设计器通过拖拽生成LVGL代码,大幅提升UI开发效率。SquareLine Studio正是这类工具的代表,支持界面设计、事件绑定与代码导出。其安装、汉化与激活是初学者常见门槛,尤其涉及LVGL版本匹配、字体配置及FreeRTOS移植等关键环节。本文围绕汉化版安装、一个月免费激活码使用及最小可用流程展开,帮助开发者快速上手LVGL界面设计,规避常见环境与集成问题。

weixin_29189987的博客 424

Java虚拟机JVM学习笔记

作为一名Java使用者,掌握JVM的体系结构也是必须的。 说起Java,人们首先想到的是Java编程语言,然而事实上,Java是一种技术,它由四方面组成:Java编程语言、Java类文件格式、Java虚拟机和Java应用程序接口(Java API)。它们的关系如下图所示: 运行期环境代表着Java平台,开发人员编写Java代码(.java文件),然后将之编译成字节码(.class文

GordonOo的专栏 2488

智算中心建设全流程指南:从规划到落地

智算中心的建设是一个复杂而系统的过程,涉及选址、立项、办理相关手续、设计、土建、机电安装、调试、验收等多个环节。每个环节都需要充分考虑各种因素,并注意相关的事项,以确保智算中心的顺利建设和高效运行

数据中心全生命周期价值管理 3399

java基础-jvm-简单整理

其实写这篇博客,压力还是很大的,因为我对JVM并不很清楚,有哪里不对的希望大家给出建议. JVM图和基本说明,这里就不做说明,比较网上一大堆资料,写一些自己整理的简单的. JVM的内存结构 1> Java虚拟机栈 : 线程私有;每个方法在执行的时候会创建一个栈帧,存储了局部变量表,操作数栈,动态连接,方法返回地址等;每个方法从调用到执行完毕,对应一个栈帧在虚拟机栈中的入栈和出栈 2> ...

小安灬的博客 231

ElaticSearchUtil工具类封装

package com.xxx.util; import org.elasticsearch.action.admin.cluster.state.ClusterStateResponse; import org.elasticsearch.action.admin.indices.analyze.AnalyzeAction; import org.elasticsearch.action.ad

会飞的狼 6295

Bootloader Design of PIC18 series MCU

注意:下列描述是在PIC单片机上启用Bootloader的一个相关知识的近似完备集。所有需要了解的,与bootloader与用户态程序交互的理论知识都已给出。包含内存组织,跳转,中断等必备功能的描述。

含光左卫的工作笔记集 1267

您的浏览器没有获得Java Virtual Machine(JVM)支持。可能由于没有安装JVM或者已安装但是没有启用。请安装JVM1.5或者以上版本,如果已安装则启用它

您的浏览器没有获得Java Virtual Machine(JVM)支持。可能由于没有安装JVM或者已安装但是没有启用。请安装JVM1.5或者以上版本,如果已安装则启用它 这是我在校外访问学校网遇到的问题 我们学校访问内网的方式就是vpn.xxxx.edu.cn 输入之后浏览器就会提示上面那段话 网上搜了一段时间,没有找到解决办法,我个人觉得这个错误提示没有很好的指导性 我目前的解决办...

weixin_37614450的博客 6万+

Hermes深入理解及源码解析(二):Hermes的记忆机制

源码位置:tools/memory_tool.py存储内容为两个文件,放在 ~/.hermes/memories/:MEMORY.md:Agent 自己的笔记(环境事实、项目约定、工具坑、学到的东西)—— 上限 2200 字符USER.md:关于用户的画像(角色、偏好、沟通风格)—— 上限 1375 字符作为一个独立的工具注册在系统中(为了让智能体正确使用它,System Prompt()中明确下达了禁令存储目标存储位置数据类型持久偏好/事实MEMORY.md我是谁、我喜欢什么、环境配置。

qq_41984117的博客 561

JVM运行的基本流程

目录前言JVM之运行流程JVM之基本结构JVM之内存空间:方法区、java堆、java栈、本地方法栈方法区java堆(Heap 堆)java栈(Stack 栈)本地方法栈总结 前言 |ू・ω・` ) 因为在很多学习的途中,如果你想去理解一个东西的本质的话,肯定得去挖掘知识的底部。 在java中,JVM一直是java知识里面进阶阶段的重要部分。 如果希望在java领域研究的更深入,那JVM则是如论如...

旺旺的博客 1万+

Cesium初级开发教程之三十:Primitive集合

教程示例网站:https://thomaz529.github.io。

484

〖Python WEB 自动化测试实战篇⑤〗- selenium 元素定位详解 - (八大元素定位方式)

测试对象的定位和操作是我们利用 selenium 编写自动化脚本和 webdriver 的核心内容,其中 "操作" 这一部分又是建立在 "selenium" 元素定位的基础之上的。所以对元素对象的定位就显得越发的重要,接下来我们就学习一下常用的元素定位方法有哪些。......

易编橙 · 终身成长社群,相遇已是上上签! 4万+

Java 详解 JVM工作原理及流程

说起Java,人们首先想到的是Java编程语言,然而事实上,Java是一种技术,它由四方面组成:Java编程语言、Java类文件格式、Java虚拟机和Java应用程序接口(Java API)。它们的关系如下图所示: 运行期环境代表着Java平台,开发人员编写Java代码(.java文件),然后将之编译成字节码(.class文件),再然后字节码被装入内存,一旦字节码进入虚拟机,它就会被解释器解...

gonghua0502的专栏 288

uniapp - 详细解决 H5 网页报错 Uncaught Error: Async component timed out after ? ms.(移动端h5页面白屏或加载缓慢失败,超时报错处理)

uni-app,vue3,网页,h5,移动端,手机H5页面,浏览器,报错,uniapp报错,Asynccomponenttimedoutafter,如何解决这个问题,vue3Asynccomponenttimedoutafter,异步组件超时了怎么办,async,详细解决方案,AsyncComponents异步组件,导致页面打不开了,白屏什么也不显示,网页载入非常慢卡顿,vue3网站报错,超时,nuxt3,详细解决方案,浏览器控制台报错,爆红并且页面卡住了,依旧报错,找不到异步组件的报错

🏆 前端领域优质创作者 3777

Java 详解 JVM 工作原理和流程

作为一名Java使用者,掌握JVM的体系结构也是必须的。 说起Java,人们首先想到的是Java编程语言,然而事实上,Java是一种技术,它由四方面组成:Java编程语言、Java类文件格式、Java虚拟机和Java应用程序接口(Java API)。它们的关系如下图所示: 运行期环境代表着Java平台,开发人员编写Java代码(.java文件),然后将之编译成字节码(.cl

luceyes 家园 7917

Probability and Statistics - 4th edition

Probability and Statistics - 4th edition

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

JAVA详解JVM工作原理和流程

说起JAVA,人们首先想到的是,java是一门编程语言,然而事实上java是一种技术,它由四部分组成:1.java编程语言、2.java类文件格式、3.java虚拟机、4.java应用程序接口。他们关系如下图所示: 运行期环境代表着JAVA平台,开发人员编写java代码(.java文件),然后再将其编译成字节码文件(.class),再然后字节码被装入内存,一旦字节码进入虚拟机,就会被解释器解释执行,或者是被即时代码发生器,准换成机器代码执行。java平台由java虚拟机与java应用程序接口搭建,ja

weixin_41631245的博客 521

visio安装包

Microsoft Office Visio 是一款专业的制图软件。利用经过更新的形状、协作工具和数据链接图表,创建专业级图表以简化复杂的信息。

java详解jvm工作原理和流程

作为一名Java使用者,掌握JVM的体系结构也是必须的。说起Java,人们首先想到的是Java编程语言,然而事实上,Java是一种技术,它由四方面组成:Java编程语言、Java类文件格式、Java虚拟机和Java应用程序接口(Java API)。它们的关系如下图所示: 运行期环境代表着Java平台,开发人员编写Java代码(.java文件),然后将之编译成字节码(.class文件),再...

Niko_Yu的博客 182

温度PID控制PLC程序

温度PID稳定控制程序,适用于欧姆龙PLC,对其他PLC也具有很大参考价值

上一篇: 购物车实现原理
下一篇: servlet request getHeader(“x-forwarded-for”) 获取真实IP
xianxing.tang
博客等级 码龄9年 5粉丝 33原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值