Java虚拟机知识点-class文件

Class文件是一组以8位字节为基础单位的二进制流,各个数据项目严格按照顺序紧凑排列在Class文件中,中间没有添加任何分隔符,这使得整个Class文件中存储的内容几乎全部是程序运行的必要数据,没有空隙。当遇到需要占用8位字节以上的数据项时,会按照高位在前的方式分割成若干个8位字节进行存储。

ClassFile 结构说明
magic:魔数。唯一作用是确定这个文件是否为一个能被虚拟机所接收的class文件。固定值:0xCAFEBABE。
minor_version:class文件的副版本号。
major_version:class文件的主版本号。
constant_pool_count:常量池计数器。
constant_pool[constant_pool_count]:常量池。包含字符串常量、类或接口名、字段名和其他常量。常量池每一项都具备相同特征,即第一个字节作为类型标记,用来确定该项格式。
access_flags:访问标志。用于表示某个类或接口的访问权限及属性。
this_class:当前的类索引。
super_class:父类索引。
interfaces_count:接口计数器。当前类或接口的直接超的接口数量。
interfaces[interfaces_count]:接口表。
fields_count:字段计数器。当前class文件的字段成员个数。
fields[fields_count]:字段表。
methods_count:方法计数器。方法的个数。
methods[methods_count]:方法表。
attributes_count:属性计数器。属性个数。
attributes[attributes_count]:属性表。
一个例子
对下面的类进行编译生成 Test2.class 。

public class Test2 {
public static int i = 1;
public static void main() {
System.out.println(i);
}
}
通过十六进制查看工具打开 Test2.class 。

根据 ClassFile 结构说明,前面4个字节是魔数oxcafebabe。接下来是次版本号和主版本号ox0000和ox0034,十进制为0和52,52表示JDK1.8,所以JDK版本是1.8.0。

还可以使用Java自带的反编译工具来解析字节码文件。命令 javap -v Test2.class 。

Classfile /E:/CODE/JVM/Test2.class
Last modified 2019-7-19; size 219 bytes
MD5 checksum 841c66674d71005bc6a97fe6c3b0fb1d
Compiled from "Test2.java"
public class Test2
minor version: 0
major version: 52
flags: ACC_PUBLIC, ACC_SUPER
Constant pool:
#1 = Methodref #4.#13 // java/lang/Object."<init>":()V
#2 = Fieldref #3.#14 // Test2.i:I
#3 = Class #15 // Test2
#4 = Class #16 // java/lang/Object
#5 = Utf8 i
#6 = Utf8 I
#7 = Utf8 <init>
#8 = Utf8 ()V
#9 = Utf8 Code
#10 = Utf8 LineNumberTable
#11 = Utf8 SourceFile
#12 = Utf8 Test2.java
#13 = NameAndType #7:#8 // "<init>":()V
#14 = NameAndType #5:#6 // i:I
#15 = Utf8 Test2
#16 = Utf8 java/lang/Object
{
public int i;
descriptor: I
flags: ACC_PUBLIC

public Test2();
descriptor: ()V
flags: ACC_PUBLIC
Code:
stack=2, locals=1, args_size=1
0: aload_0
1: invokespecial #1 // Method java/lang/Object."<init>":()V
4: aload_0
5: iconst_1
6: putfield #2 // Field i:I
9: return
LineNumberTable:
line 1: 0
line 2: 4
}
SourceFile: "Test2.java"
Java虚拟机限制
每个类或接口的常量池最多65535个。
类或接口中可声明的字段数最多65535个。
类或接口中可声明的方法数最多65535个。
类或接口的直接父类接口最多65535个。
方法调用时创建的栈帧,其局部变量表中的最大局部变量数位65535个。
方法帧中操作数栈的最大深度为65535。
方法的参数最多255个。
字段和方法名称、字段和方法描述符以及其他常量字符串值的最大长度为65535个字符。
数组的维度最大为255维。
喜欢这篇文章的可以给笔者点个赞同,关注一下,每天都会分享Java相关文章!还有不定时的福利赠送,包括整理的学习资料,面试题,源码等~~

原文地址:https://blog.51cto.com/14440597/2424364

时间: 2024-11-02 03:17:02

Java虚拟机知识点-class文件的相关文章

深入理解Java虚拟机04--类结构文件

一.程序存储格式 统一的程序存储格式:不同平台的虚拟机于所有平台都统一使用程序存储格式--字节码(ByteCode); Java 虚拟机不关心 Class 文件的来源,而只和"Class文件"这种二进制文件格式关联,也就是说Java虚拟机只认识"Class"文件: Java 编译器可以把 Java 程序代码编译成虚拟机所需要的Class 文件: 二.Class 文件结构 Class 文件是以 8 个字节为单位的二进制流,紧凑排列,中间没有空隙:如果想查看一个 Cla

Java虚拟机知识点【引用】

??Java虚拟机采用可达性分析算法来判断对象是否可以回收.可达性分析算法通过一系列的GC Roots对象作为起始点,向下搜索走过的路径称引用链,当一个对象到GC Roots没有任何的引用链时,证明对象是不可用的. Java中,可作为GC Roots的对象: 虚拟机栈中引用的对象 本地方法栈的JNI引用的对象 方法区静态属性引用的对象 方法区常量引用的对象 Java对引用进行了扩充,分为强引用.软引用.弱引用.虚引用四种. 强引用:(StrongReference) 强引用是使用最普遍的引用.如

Java内存区域 - 深入Java虚拟机读后总结

Java虚拟机在执行Java程序的过程中会把所管理的内存划分为若干个不同的数据区域,这些区域有各自的用途,有各自的创建时间和销毁时间,有的区域随着虚拟机进程的启动而存在,有的区域则是依赖用户线程的启动和结束进行建立或销毁.Java虚拟机第二版规定,虚拟机管理的内存包含以下几个运行时数据区域 程序计数器:程序计数器(Program Counter Register)是一块较小的内存空间,作用可以理解为是当前线程所执行的字节码的行号指示器.Java虚拟机的多线程是通过线程切换以及分配处理器执行时间来

Java虚拟机-保险沙箱

Java虚拟机-安全沙箱 <Java虚拟机>-安全沙箱 学习了一下Java的安全机制,以前学习C++的时候好像就从来没有考虑过太多安全方面的问题,一些代码方面的安全问题,诸如指针.内存什么的考虑过,但是整体的安全性基本无视,学习了这一章还是有蛮多收获. 沙箱 组成沙箱的四个组件: 类装载器 class文件检验器 Java虚拟机内置的安全特性 安全管理器 类装载器 通过命名空间隔离类,使不同命名空间的类不会互相访问(显示指定了访问方式的例外),解决了类的访问范围问题,如下图: 类的加载(装载)顺

Java虚拟机 运行时数据区

Java在执行Java程序的过程中会把它所管理的内存划分为若干个不同的数据区域.这些区域都有各自的用途.创建和销毁的时间,有一些是随虚拟机的启动而创建,随虚拟机的退出而销毁,有些则是与线程一一对应,随线程的开始和结束而创建和销毁. Java虚拟机所管理的内存将会包括以下几个运行时数据区域 程序计数器(Program Counter Register) 它是一块较小的内存空间,它的作用可以看做是当先线程所执行的字节码的信号指示器. 每一条JVM线程都有自己的PC寄存器,各条线程之间互不影响,独立存

深入理解Java虚拟机:运行时数据区域

Java虚拟机在执行Java程序的过程中会把它所管理的内存划分为若干个不同的数据区域.这些区域都有各自的用途,以及创建和销毁的时间,有的区域随着虚拟机进程的启动而存在,有些区域则依赖用户线程的启动和结束而建立和销毁.根据<Java虚拟机规范(Java SE 7版)>的规定,Java虚拟机所管理的内存将会包括以下几个运行时数据区域. 程序计数器 程序计数器(Program Counter Register)是一块较小的内存空间,它可以看作是当前线程所执行的字节码的行号指示器.在虚拟机的概念模型里

Java虚拟机内存分配详解

简介 了解Java虚拟机内存分布的好处 1.了解Java内存管理的细节,有助于程序员编写出性能更好的程序.比如,在新的线程创建时,JVM会为每个线程创建一个专属的栈 (stack),其栈是先进后出的数据结构,这种方式的特点,让程序员编程时,必须特别注意递归方法要尽量少使用,另外栈的大小也有一定的限制,如果过多 的递归,容易导致stack overflow. 2.了解Java内存管理的细节,一旦内存管理出现问题,有助于找到问题的根本原因所在. 3.了解Java内存管理的内幕,有助于优化JVM,从而

java虚拟机学习(四)类的加载过程

类从虚拟机内存加载到从内存卸载,经历的生命周期是:加载,验证,准备,解析,初始化,使用,卸载这几个阶段, 其中验证,解析,初始化被称为 连接过程(Linking). (打算这块和类加载原理后再看class文件结构那篇) 除了解析和使用,其他的过程基本顺序就是这样, 解析可以是在初始化完成之后,这是为了运行时动态绑定. 在虚拟机规范中定义了5中情况(有且只有)必须对类进行初始化(之前进行过,加载,验证,准备): 1.碰到new,getstatic,putstatic,invokestatic这4条

《深入理解Java虚拟机》笔记02:Java内存区域与内存溢出异常

1.运行时数据区域 Java虚拟机在执行Java程序的过程中会把它所管理的内存划分为若干个不同的数据区域.这些区域都有各自的用途,以及创建和销毁的时间: 有的区域随着虚拟机进程的启动而存在 有些区域则依赖用户线程的启动和结束而建立和销毁 根据<Java虚拟机规范(Java SE 7版)>的规定,Java虚拟机所管理的内存将会包括以下几个运行时数据区域,如图所示. 1.1 程序计数器 程序计数器(Program Counter Register)是一块较小的内存空间,它可以看作是当前线程所执行的