Java程序运行原理
Java程序运行:需要将其编译成class文件,然后再运行
一、java程序运行原理
一)java运行原理图
引用https://blog.csdn.net/naoguoteng/article/details/123482656
1、class文件内容
class文件包含java程序执行的字节码
数据严格按照格式紧凑排列在ckass文件中的二进制限流,中间无任何分隔符;文件开头有一个0xcafevase(16进制)特殊的一个 标志
# 编译java源码
javac Hello.java
# 查看class文件
javap -v Hello.class > Hello.txt
class内容——版本号/访问控制
版本号规则:JDK5/6/7/8分别对应49,50,51,52
访问标志
·
class内容——常量池
class内容——构造方法
没有定义构造函数时,会隐式的无参构造函数
class内容——程序入口main方法
描述了方法的
- 访问控制
- 本地变量数量
- 参数数量
- 方法对应栈帧中操作数栈的深度
- JVM执行引擎去执行这些源码编译过后的指令码。javap翻译出来是操作符,class文件内存储的是指令码。前面的数字是偏移量(字节),jvm根据这个去区分不同的指令
2、JVM运行时
数据区
线程独占:每个线程都会有它独立的空间,随线程生命周期而创建和销毁
线程共享:所有线程能访问这块内存数据,随虚拟机或GC而创建和销毁
方法区
JVM用来存储加载的类信息、常量、静态变量、编译后的代码等数据
虚拟机规范中这是一个逻辑区划,具体实现根据不同虚拟机来实现。
堆内存
堆内存还可以细分为:老年代、新生代(Eden、From Survisor、To Survisor)
JVM启动时创建,存放对象的实例。垃圾回收器主要就是管理堆内存。若满了就会出现OutOfMemroyError
虚拟机栈
虚拟机栈:每个线程都在这个空间有一个私有的空间
线程栈由多个线帧(Stack Frame)组成
一个线程执行一个或多个方法,一个方法对应一个栈帧
栈帧内容包含:局部变量表、操作数栈、动态链接、方法返回地址、附加信息等
栈内存默认最大是2M,超出则抛出StackOverflowError
本地方法栈
和虚拟机栈功能类似,虚拟机栈是为虚拟机执行java方法而准备的。本地方法栈是为虚拟机使用Native本地方法而准备的
虚拟机规范没有规定具体的实现,由不同的虚拟机厂商去实现。
HotSpot虚拟机中虚拟机栈和本地方法栈的实现式一样的。同样,超出大小以后也会抛出StackOverflowError。
程序计数器
程序计数器(Program Counter Register)记录当前线程执行字节码的位置,存储的是字节码指令地址,若执行Native方法,则计数器值为空
每个线程都在这个空间有一个私有的空间,占用内存空间很少。
CPU同一时间,只会执行一条线程中的指令,JVM多线程会轮流切换并分配CPU执行时间的方式。为了线程切换后,需要通过程序计数器,来恢复正确的执行位置。
二)java虚拟机
JVM是java语言最大的特点。java的优缺点也是源于JVM技术。
JVM是一个可运行java字节码的虚拟计算机系统。
JVM有一个解释器组件,可以实现Java字节码和计算机操作系统之间的通信。还包括一组寄存器、一个栈、一个垃圾回收堆和一个存储方法域
JVM屏蔽了与具体操作系统平台相关的信息,使Java程序只需生成在Java虚拟机上运行的字节码,就可以在多种平台上不加修改地运行。这个也是java最大的特色跨平台性,也就是一处编写,处处运行。JVM在执行字节码时,实际上最终还是把字节码解释成具体平台上的机器指令执行。
编译虚拟机的指令集与编译微处理器的指令集非常类似。这就是java最受人批评的一个地方,运行在JVM上面当然没有直接运行在操作系统上快。所以有人总是说java的运行速度比不上C语言。
三)分析程序
1、符号 /* */ 指示中间的语句是该程序中的注释。多行注释以 /* 开始,以 */ 结束。单行注释以 // 开始,以行末结束,java文档注释使用/** */。 2、关键字 class 声明类的定义,还帮助编译器理解它是一个类的声明。 3、整个类及其所有成员都是在一对大括号中(即 { 和 } 之间)定义的。它们标志着类定义块的开始和结束。 4、程序从 main( ) 方法开始执行。 5、关键字 public 是一个访问说明符,控制类成员的可见度和作用域。 6、关键字 static 允许调用 main( ) 方法,而无需创建类的实例。 7、关键字 void 告诉编译器 main( ) 方法在执行时不返回任何值。 8、main( )方法是所有Java 应用程序的起始点。 9、args[ ]是String类型的数组。 10、println( )方法通过 System.out 显示作为参数传递给它的字符串。
四)程序完整运行分析