后端精进笔记01:class文件在JVM是如何运行的
2020/3/11 17:01:42
本文主要是介绍后端精进笔记01:class文件在JVM是如何运行的,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
本文主要讲述Java代码在JVM中是如何执行的.
一、概述:
Java代码的一生大致如下图所示,其中,JVM运行时数据区是我们需要重点关注的部分:
1.1 所有线程共享部分
方法区:存储JVM加载的类信息、常量、静态变量、编译后的代码等数据。在虚拟机规范中,对于方法区的定义是一个不严谨的、逻辑上的概念,实际上各虚拟机会有不同的实现。
堆内存:JVM启动时创建该区域,主要用于存储对象的实例,GC垃圾回收主要是处理堆内存。
1.2 各线程独有部分
栈内存:或称为虚拟机栈,由多个栈帧组成,一个JVM线程会执行一个或多个方法,而__一个方法对应一个栈帧__。一个栈帧包括:局部变量表、操作数栈等部分。每个线程的栈内存大小默认是1M,超出则报StackOverflowError。
本地方法栈:顾名思义,是为JVM执行native方法准备的。
程序计数器:由于CPU在单位轮片时间内,只执行一个线程的指令。每个线程的程序计数器记录当前线程执行的字节码位置,存储的是字节码的地址(如果执行的native方法,则计数器数值为空)。这样在线程切换出去再切换回来时,就能找到上次执行的指令位置,然后继续执行。
二、小试牛刀:class字节码文件内容追踪
2.1 准备工作
2.1.1 Demo.java
public class Demo01 { public static void main(String[] args) { int a = 200; int b = 100; int c = a / b; int d = 3; System.err.println(c + d); } } 复制代码
2.1.2 编译(javac)并解析(javap)Demo.class
# 编译 javac Demo01.java # 解析。并将指令内容输出到Demo01.txt中 javap -v Demo01.class > Demo01.txt 复制代码
2.1.3 分析class文件中的指令
解析后的指令内容如下:
Classfile /Users/zephyrlai/IdeaProjects/zephyr/java-arch/src/cn/zephyr/ch1/Demo01.class Last modified 2020-3-10; size 429 bytes MD5 checksum 5c8846f77018cc43a36eeba64ff68cbd Compiled from "Demo01.java" public class cn.zephyr.ch1.Demo01 minor version: 0 major version: 52 flags: ACC_PUBLIC, ACC_SUPER Constant pool: #1 = Methodref #5.#14 // java/lang/Object."<init>":()V #2 = Fieldref #15.#16 // java/lang/System.err:Ljava/io/PrintStream; #3 = Methodref #17.#18 // java/io/PrintStream.println:(I)V #4 = Class #19 // cn/zephyr/ch1/Demo01 #5 = Class #20 // java/lang/Object #6 = Utf8 <init> #7 = Utf8 ()V #8 = Utf8 Code #9 = Utf8 LineNumberTable #10 = Utf8 main #11 = Utf8 ([Ljava/lang/String;)V #12 = Utf8 SourceFile #13 = Utf8 Demo01.java #14 = NameAndType #6:#7 // "<init>":()V #15 = Class #21 // java/lang/System #16 = NameAndType #22:#23 // err:Ljava/io/PrintStream; #17 = Class #24 // java/io/PrintStream #18 = NameAndType #25:#26 // println:(I)V #19 = Utf8 cn/zephyr/ch1/Demo01 #20 = Utf8 java/lang/Object #21 = Utf8 java/lang/System #22 = Utf8 err #23 = Utf8 Ljava/io/PrintStream; #24 = Utf8 java/io/PrintStream #25 = Utf8 println #26 = Utf8 (I)V { public cn.zephyr.ch1.Demo01(); descriptor: ()V flags: ACC_PUBLIC Code: stack=1, locals=1, args_size=1 0: aload_0 1: invokespecial #1 // Method java/lang/Object."<init>":()V 4: return LineNumberTable: line 9: 0 public static void main(java.lang.String[]); descriptor: ([Ljava/lang/String;)V flags: ACC_PUBLIC, ACC_STATIC Code: stack=3, locals=5, args_size=1 0: bipush 200 2: istore_1 3: sipush 100 6: istore_2 7: iload_1 8: iload_2 9: idiv 10: istore_3 11: iconst_3 12: istore 4 14: getstatic #2 // Field java/lang/System.err:Ljava/io/PrintStream; 17: iload_3 18: iload 4 20: iadd 21: invokevirtual #3 // Method java/io/PrintStream.println:(I)V 24: return LineNumberTable: line 11: 0 line 12: 3 line 13: 7 line 14: 11 line 15: 14 line 16: 24 } SourceFile: "Demo01.java" 复制代码
可以看到大致可以分为如下4块
-
前4行:无关代码内容的描述信息
-
5~8行:版本号、访问标志
-
(major-verion)版本号:jdk5、6、7、8分别是49、50、51、52
-
访问标志:
标志名称 标志值 含义 ACC_PUBLIC 0x0001 标记为public类型 ACC_FINAL 0x0010 标记被声明为final(仅类能设置) ACC_SUPER 0x0020 jdk1.2之后为true(是否使用invokespecial字节码指令) ACC_INTERFACE 0x0200 标记为接口 ACC_ABSTRACT 0x0400 标记为abstract类型(对于接口、抽象类则为true) ACC_SYNTHETIC 0x1000 标记这个类不是用户产生的 ACC_ANNOTATION 0x2000 标记为注解类 ACC_ENUM 0x4000 标记为枚举类
-
-
以Constant pool为起点的常量池(区别于String常量池):主要存储类信息中包含的静态常量,即编译当前类之后,所用到的常量。例如类名、方法名等。常见的常量类型如下:
-
以
{}
包裹的业务代码,而这块业务代码包含了2块:- 默认无参构造器
- main方法
- flags:依旧是访问控制
- Code下的
stack=3, locals=5, args_size=1
则分别表示本地变量数量为3、参数数量为5、(方法对应的)栈帧中操作数栈的深度为1 - 剩下的即为业务代码
2.2 程序运行分析
2.2.1 加载class文件
主要加载各种类信息、以及类中用到的常量、静态变量等,存储在方法区。创建类的实例,存储在堆内存中。
2.2.2 JVM创建线程来执行代码
开辟各线程独立的虚拟机栈(包括多个栈帧)、程序计数器等内存空间
2.2.3 字节码执行分析
参考
这篇关于后端精进笔记01:class文件在JVM是如何运行的的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-10-01基于Python+Vue开发的医院门诊预约挂号系统
- 2024-10-01基于Python+Vue开发的旅游景区管理系统
- 2024-10-01RestfulAPI入门指南:打造简单易懂的API接口
- 2024-10-01初学者指南:了解和使用Server Action
- 2024-10-01Server Component入门指南:搭建与配置详解
- 2024-10-01React 中使用 useRequest 实现数据请求
- 2024-10-01使用 golang 将ETH账户的资产平均分散到其他账户
- 2024-10-01JWT用户校验课程:从入门到实践
- 2024-10-01Server Component课程入门指南
- 2024-09-30Dnd-Kit学习:新手快速入门指南