java一直宣传的口号是:一次编译,到处运行。那么它如何实现的呢?我们看下图:
java程序经过一次编译之后,将java代码编译为字节码也就是class
文件,然后在不同的操作系统上依靠不同的java虚拟机
进行解释,最后再转换为不同平台的机器码,最终得到执行。这样我们是不是可以推演,如果要在mac系统上运行,是不是只需要安装mac java虚拟机
就行了。那么了解了这个基本原理后,我们来看一下,一段程序是如何执行的。
public class helloworld { public static void main(string[] args) { system.out.print("hello world"); } }
这段程序从编译到运行,所经历的过程如下:
可能通过上面的描述,大家对jvm运行流程有了一个粗略的认识,那么jvm内部到底是怎么执行一个class文件的呢?
jvm内存空间包含:方法区、java堆、java栈、本地方法栈。
方法区是各个线程共享
的区域,存放类信息、常量、静态变量。
java堆也是线程共享
的区域,我们的类的实例就放在这个区域,可以想象你的一个系统会产生很多实例,因此java堆的空间也是最大的。如果java堆空间不足了,程序会抛出outofmemoryerror异常。
java栈是每个线程私有
的区域,它的生命周期与线程相同,一个线程对应一个java栈,每执行一个方法
就会往栈中压入一个元素,这个元素叫“栈帧”,而栈帧
中包括了方法中的局部变量、用于存放中间状态值的操作栈,如果java栈空间不足了,程序会抛出stackoverflowerror异常.
每个帧代表一个方法,java方法有两种返回方式,return和抛出异常,两种方式都会导致该方法对应的帧出栈和释放内存。
本地方法栈角色和java栈类似,只不过它是用来表示执行本地方法的,本地方法栈存放的方法调用本地方法接口,最终调用本地方法库,实现与操作系统、硬件交互的目的。
pc寄存器(程序计数器),说到这里我们的类已经加载了,实例对象、方法、静态变量都去了自己改去的地方,那么问题来了,程序该怎么执行,哪个方法先执行,哪个方法后执行,这些指令执行的顺序就是pc寄存器在管,它的作用就是控制程序指令的执行顺序。
执行引擎当然就是根据pc寄存器调配的指令顺序,依次执行程序指令。
- 静态变量+常量+类信息+运行时常量池存在方法区中,实例变量存在堆内存中。
- 基本类型的变量和对象的引用变量都是在函数的栈内存中分
如对本文有疑问, 点击进行留言回复!!
unity的错误解决办法:NullReferenceException: Object reference not set to an instance of an object;tiny proje
Hadoop 之 HDFS (HDFS 数据流的 读写 流程)
听说你一读Spring源码就懵逼?我帮你把架子搭好了,你填就行!
首席架构师推荐:金融保险领域数字化转型实践--如何优雅地修改业务中台中分层应用Maven多模块的版本号?(命令导入式)
[JVM学习之路]一、初识JVM,了解其结构、模型及生命周期
网友评论