一、Class类结构:
class文件是以8位字节为基础单位的二进制流。
ClassFile {
u4 magic;//魔数(0xCAFEBABE。固定值)
u2 minor_version;//次版本号
u2 major_version;//主版本号
u2 constant_pool_count;//常量池容量计数值
cp_info constant_pool[constant_pool_count-1];//常量池
u2 access_flags;//访问标志
u2 this_class;//类索引
u2 super_class;//父类索引
u2 interfaces_count;//接口计数器
u2 interfaces[interfaces_count];//接口索引集合
u2 fields_count;//字段计数器
field_info fields[fields_count];//字段表
u2 methods_count;//方法计数器
method_info methods[methods_count];//方法表
u2 attributes_count;//属性表计数器
attribute_info attributes[attributes_count];//属性表集合
}
常量池的项目类型如下(每一种类型的可以看作一种数据结构):
Class_info型的结构如下:
类型 | 名称 | 数量 |
u1(占用一个字节) | tag=7 | 1 |
u2(占用两个字节) | name_index(指向常量池中utf8_info类型的常量) | 1 |
类型 | 名称 | 数量 |
u1 | tag=1 | 1 |
u2 | length(长度) | 1 |
u1 | bytes | lenth |
可以使用javap命令分析class文件字节码:到class文件所在的文件夹,然后运行javap -verbose xxxxx(这个是类名)
javac在编译的时候把this关键字作为一个普通的方法参数的访问,然后虚拟机在调用实例的时候自动传入此参数。
LineNumberTable属性用于描述java源文件行号和字节码行号的对于关系,调试可以对应起来行号。LocalVariableTable属性记录局部变量表之间的变量和源码中定义的变量之间的关系,这样在调试的时候可以对应起来变量,另外才可以通过程序得到入参的名字。
对于泛型虽然运行时进行了类型擦除,但是通过Class元数据依然可以获得泛型的信息是因为LocalVariableTypeTable.
二、虚拟机类加载机制
java类加载的时机:1、遇到new /putstatic /getstatic/invokestatic指令 2、java.lang.Class反射调用3、父类加载4、main方法第一个加载。
类加载的过程:
1、加载:获得二进制流、在方法区转化为运行时结构、在堆中生成java.lang.Class对象
2、校验:校验二级制流、校验类。。。
3、准备:为类变量在方法区分配内存空间
4、解析:实际上也是校验的过程。把符号引用解析为直接引用的过程。
5、初始化:clinit方法,并调用static代码。在初始化的工程中会加锁与同步,如果static块中很耗时,可能会造成线程阻塞。
java会对数组类型创建一个类,会有length和clone方法。
类加载器:
启动类加载器:加载<JAVA_HOME>\lib目录下或者被-Xbootclasspath参数指定的路径,并且被虚拟机识别的
扩展类加载器:加载<JAVA_HOME>\lib\ext目录中,或者被java.ext.dirs系统变量指定的类库。父加载器是启动类加载器。
应用程序类加载器:有sun.misc.Launcher$AppClassLoader实现,加载classPath自动的类库,父加载器是扩展类加载器。是ClassLoader。getSystemClassLoader()的返回值。
三、虚拟机字节码执行引擎
1、运行时栈的结构:包括局部变量表。局部变量表中的Slot是可以重用的。操作数栈:编译器最大操作数栈已经确定。动态链接:包含指向运行时常量池中该栈帧所属方法的引用。方法返回地址。
2、方法调用:A.解析调用是一个静态的工程,属于编译器可知。
B、静态分派:重载的运用,重载的时候是通过参数的静态类型而不是实际类型作为判断依据的。发生在编译阶段。
C:动态分派:重写的运用。会在运行态决定执行的方法。首先查找本类的方法,如果找不到就查找父类。由于动态分派是什么频繁的过程,虚拟机会为类中创建一个虚方法表,来代替元数据查找提高性能。一般在初始化阶段把类的方法表也初始化。
虚方法表中存放着各个方法的入口,如果子类没有重写,那么子类和父类的方法入口是一样的,如果重写了,子类方法表的地址将会替换为指向子类实现版本的入口地址.
虚方法表中存放着各个方法的入口,如果子类没有重写,那么子类和父类的方法入口是一样的,如果重写了,子类方法表的地址将会替换为指向子类实现版本的入口地址.
基于栈的解释执行引擎:
解释执行:通过解释器执行,基于操作数栈(可移植性好)
编译执行:通过即时编译器产生本地代码执行,本地代码会放在方法区。
相关推荐
《深入理解Java虚拟机》阅读笔记 本repository为《深入理解Java虚拟机 - Jvm高级特性与最佳实践(第三版)》阅读笔记,因为第一章主要讲的是Java的发展历史,这里就不做笔记,直接从第2章的"Java内存区域与内存溢出...
**JVM学习笔记(Java虚拟机)** Java虚拟机(JVM)是Java语言的核心组成部分,它是Java程序运行的平台,负责解释和执行字节码。深入理解JVM对于优化Java应用程序性能至关重要。本笔记将从以下几个方面详细介绍JVM:...
【标题】: JVM执行子系统解析 - Class文件结构详解 【描述】: 本文深入探讨JVM执行子系统的核心组成部分,特别是围绕Java Class文件结构展开,解析其在跨平台执行中的关键角色。 【正文】: Java虚拟机(JVM)是...
深入理解java虚拟机:jvm高级特性与最佳实践源码现代操作系统,第 4 版 作者:Andrew S. Tanenbaum, Herbert Bos ** Notes by Henry Cooksley ** 1 介绍 操作系统、外壳、GUI、图形用户界面、内核模式、主管模式、...
9. **JVM原理**:理解Java虚拟机的工作原理对于优化代码和排查问题至关重要。笔记可能涵盖类加载、内存模型、垃圾回收等话题。 10. **设计模式**:设计模式是软件开发中的最佳实践,如单例模式、工厂模式、装饰器...
### Java课堂笔记学习 #### 软件定义与软件开发 - **软件**:软件是运行在硬件之上的一组指令集,这些指令集能够完成特定的功能。软件开发过程包括设计和编码两个主要阶段。 #### 编程语言的重要性 - **编程语言...
在 Java 虚拟机退出时,Daemon 线程中的 finally 块并不一定会执行。 构造线程 一个新构建的线程对象是由其父线程来进行空间分配的,而子线程继承了父线程的是否为 Daemon、优先级和加载资源的 contextClassLoader...
- **解释性**:Java程序首先被编译为字节码,然后由Java虚拟机解释执行。 - **高性能**:通过即时编译器(JIT)将频繁执行的代码转换为机器码,提高了运行效率。 - **分布式**:支持网络透明性,可以像访问本地资源...
- JVM(Java Virtual Machine)是Java虚拟机,它是Java跨平台的关键,负责执行字节码。 - JRE(Java Runtime Environment)包含了JVM和Java的核心类库,提供了运行Java应用程序的环境。 - JDK(Java Development ...
### 郝斌Java笔记知识点概览 #### 一、Java 概述 - **起源与发展**:Java 语言起源于 Sun 公司的 ...以上内容涵盖了郝斌 Java 笔记中的核心知识点,通过学习这些基础知识,可以为深入探索 Java 技术栈打下坚实的基础。
Java虚拟机的体系结构由多个关键组件构成,包括但不限于类装载子系统、运行引擎、方法区、堆、Java栈、程序计数器和本地方法栈等。这些组件共同协作,支持Java程序的高效执行。 1. **类装载子系统**:负责从文件...
- **java**: 启动Java虚拟机(JVM)执行class文件。 - **javac**: Java源代码编译器,将.java文件编译成.class文件。 - **jar**: Java打包工具,用于创建.jar文件。 - **javadoc**: Java文档生成工具,根据源代码中的...
- **JVM (Java Virtual Machine)**:Java虚拟机,负责执行由JDK编译器生成的字节码(.class文件)。 ##### 在Linux下配置Java环境 - 配置文件路径:`/etc/profile` - 使用`cat /etc/profile`查看配置文件内容。 - **...
JVM 是 Java 虚拟机,JRE 是 Java 执行环境,JDK 是 Java 开发工具包。Java SE 提供了基本的 JavaSE API,包括字符串处理、例外处理、对象容器、输入输出和线程等。 Java EE 是 Java 平台的企业版,提供了分布式、...
Java通过Java虚拟机(JVM)实现跨平台运行,具有高效、安全、稳定的特点。 2. **Java环境配置**: 开始学习Java前,需要安装Java Development Kit(JDK),并配置好环境变量,包括`JAVA_HOME`、`PATH`和`CLASSPATH...
### Java IO流知识点详解 #### 一、Java IO流概述 在Java中,输入/输出(Input/Output,简称IO)操作是程序与外部设备进行数据交换的重要方式。Java提供了强大的IO流处理类库...这对于理解Java文件系统操作至关重要。