【深入理解JVM】学习笔记——-6、类文件结构

JVM-01 JVM内存结构 文章目录1.JVM整体架构1.1 JVM(虚拟机)1.2 Java虚拟机阵营2.JVM子系统构成3.JVM内存结构3.1 名词解释3.2 JVM对该区域规范了两种异常3.3 实例详解Java栈3.4 栈+堆+方法区的交互关系3.5 堆(线程共享)3.5.1 **为什么jdk1.8用元数据区取代了永久代**?3.5.2 java虚拟机调优的目的3.6 JVM执行案例分析3.6.1 编写java类3.... 阅读详情

你只管努力,

——剩下的交给时光。

1.概述

write one, run everywhere。

2. 无关性的基石

实现语言无关性的基础是虚拟机和字节码存储格式。Java虚拟机不和任何语言绑定,它只与"class文件"这种特定的二进制文件格式所关联。如下图所示:

Java虚拟机提供的语言无关性

3.Class类文件的结构

任何一个Class文件都对应着唯一一个类或接口的定义信息,但类或接口并不一定都得定义在文件里,也可以通过类加载器直接生成。
注意,这里所称的"Class文件"格式只是为了理解简单,实际上它并不一定以磁盘文件的形式存在。由于它没有任何分隔符号,所以无论是顺序还是数据量,它的数据项都是被严格限定的。

Class文件是一组以8字节为基础单位的二进制流,Class文件格式采用一种类似于C语言结构体的伪结构来存储数据。这种伪机构只有两种数据类型:无符号数和表。

无符号数属于基本的数据类型,以u1、u2、u4、u8来分别代表1、2、4、8个字节的无符号数,无符号数可以用来表述数字、索引引用、数量值或者按照UTF-8编码构成的字符串值。

表由多个无符号数或者其他表作为数据项构成的复合数据类型,所有表都习惯性的以"info"结尾。表用于描述有层次关系的复合结构的数据,整个Class文件本质上就是一张表,下图是它的数据项构成。

Class文件格式

无论是无符号数还是表,当需要描述同一类型但数量不定的多个数据时,经常会使用一个前置的容量计数器加若干个连续的数据项的形式,这一系列连续的某一类型的数据为某一类型的集合。

3.1 魔数与Class文件的版本

每个Class文件的头4个字节称为"魔数",唯一的作用是确定这个文件是否为一个能被虚拟机接受的Class文件。(很多文件存储标准中都使用魔数来进行身份识别,例如gif、jpeg等文件头中都有魔数)。Class文件的魔数值为:0xCAFEBABY。

紧接着魔数的4个字节存储的是Class文件的版本号:第5和第6个字节是次版本号(Minor Version),第7和第8个字节是主版本号(Major Version)。Java的版本号是从45开始,JDK1.1之后的每个JDK大版本发布主版本号向上加1(JDK1.0~JDK1.1使用了45.0~45.3),高版本号能向下兼容,但不能运行以后版本但Class文件。即使文件格式没有发生变化,虚拟机也必须拒绝执行超过其版本号的Class文件。

例如,JDK1.1支持版本号为45.0~45.65535的Class文件,无法执行版本号为46.0以上的Class文件。而JDK1.2能支持45.0~45.65535的。

下面是一个小demo:

 

public class TestClass{
        private int m;
        public int inc() {
                return m+1;
        }
}

下图是作者使用WinHex打开Class文件的效果。

Java Class 文件的结构

3.2 常量池

常量池中的常量数量是不固定的,常量池入口需要放置一个u2类型的数据,代表常量池容量计数值。这个容量的计数是从1开始的,例如下图所示:

常量池结构

常量池容量(偏移地址:0x00000008)是0x0016,即十进制的22。表示常量池中有21个常量,索引范围是1~21。第0项常量空出来目的在于满足后面某些指向常量池的索引值的数据在特定情况下需要表达"不引用任何一个常量池项目"的含义,把索引值置为0来表示。

Class文件结构中只有常量池的容量从1开始,其他集合类型如接口索引结合、字段表集合、方法表集合等的容量计数都从0开始的。

常量池主要放量大类常量:字面量和符号引用。

字面量:如文本字符串、声明为final的常量值等。

符号引用包括一下三类常量:

  • 类和接口的权限定名

  • 字段的名称和描述符

  • 方法的名称和描述符

常量池中每一项常量都是一个表。1.7之前是11种,1.7及以后为了更好的支持动态语言调用,额外增加了3中(CONSTANT_MethodHandle_info、CONSTANT_MethodType_info、CONSTANT_InvokeDynamic_info)。

这14种表都有一个共同的特点,表开始的第一位是u1类型的标识位,这14种常量类型代表的具体含义如下所示:

常量池的项目类型

JDK的bin目录中,有用于分析Class文件字节码的工具:javap。使用如下图所示:

使用javap命令输出常量表

它帮助我们把整个常量池的21项常量都计算了出来。有些常量没有在代码里出现过,它是自动生成的。

下图是常量池中的14种常量项的结构总表:

常量项总表结构(上)

常量项总表结构(下)

3.3 访问标志

常量池结束后,紧接着是2个字节的访问标志,用于识别一些类或者接口层次的访问信息:这个Class是类还是接口;是否定义为public;是否声明为final等。具体标志为如下图:

访问标志

访问标志一共16个标志位可以使用,当前只定义了8个,没有使用到的标志位要求一律为0。

3.4 类索引、父类索引与接口索引集合

类索引、父类索都是一个u2类型的数据,而接口索引集合是一组u2类型的数据集合,Class文件中由这三项数据来确定这个类的继承关系。除了java.lang.Object外所有的类都有父类,所以只有它的父类索引为0。

类索引、父类索引、接口索引集合都排在访问标志之后,类索引和父类索引各自指向一个类型为CONSTANT_Class_info的类描述符常量,通过CONSTANT_Class_info类型的常量中的索引值可以找到定义在CONSTANT_Utf8_info常量中的全限定名字字符串。

下图演示了类索引查找过程:

类索引查找全限定名的过程

接口索引集合:入口的第一项u2类型的数据为接口计数器,表示索引的容量。如果该类没有实现任何接口,计数器为0,后面的索引表不占用任何字节。如下图所示:

类索引、父类索引、接口索引集合

从偏移地址0x000000F1开始的3个u2类型的值分别是0x0001、0x0003、0x0000,也就是类索引是1,父类索引是3,接口索引集合大小为0。对应前面使用javap查询的常量池,找出对应的类和父类常量如下所示:

3.5 字段表集合

用于描述接口或者类中声明的变量。字段包括类级变量及实例级变量,但不包括在方法内部声明的局部变量。

下图是字段表的最终格式:

字段表结构

字段修饰符放在access_flas中,是一个u2的数据类型,可以设置的标志位和含义如下图:

字段访问标志

跟随access_flags标志的是两项索引值:name_index和descriptor_index。都是对常量池对引用,分别代表着字段对简单名称以及字段和方法的描述符。

方法和字段的描述符作用是:描述字段的数据类型、方法的参数列表(包括数量、类型以及顺序)和返回值。根据描述符规则,基本数据类型以及代表无返回值的void类型都用一个大写字符表示,对象类型用字符L加对象全限定名表示,如下图:

描述符标识字符含义

对于数组类型,每一个维度使用一个前置的"["字符来描述,如定义为"java.lang.String[][]"被记录为"[[Ljava/lang/String",一个"int[]"被记录为"[I"。

描述符来描述方法时,按照先参数列表,后返回值的顺序描述,参数列表按照参数的严格顺序存放在一组小括号"()"之内。如void inc()的描述符为"()V";方法java.lang.String toString的描述符为"()Ljava/lang/String";方法int indexOf(char[] source,int sourceOffset)描述符为"([CI)I"。

3.6方法表集合

方法表和字段表描述很相似,数据项目含义仅在访问标志和属性表集合的可选项中有所区别,如下图所示:

方法表结构

它所有的标志为及取值见下表:

方法访问标志

3.7属性表集合

不再要求各个属性具有严格顺序,只要不与已有属性名重复,任何人实现的编译器都可以向属性表中写入字节定义的属性信息,Java虚拟机会忽略掉它不认识的属性。预定义属性已20多项如下表:

虚拟机规范预定义的属性的一部分(上)

虚拟机规范预定义的属性的一部分(下)

对于每个属性,它的名称需要从常量池中引用一个CONSTANT_Utf8_info类型的常量来表示,而属性值的结构是完全自定义的,只需要通过u4的长度属性说明属性值所占用的位数即可:

属性表结构

1.Code属性

Code属性表的结构

attribute_name_index是一项指向CONSTANT_Utf8_info型常量的索引,常量值固定为"Code",它代表了该属性的属性名称。

attribute_length指示了属性值的长度,由于属性名称索引与属性长度一共6字节,所以属性值的长度固定为整个属性表长度减去6个字节。

max_stack代表操作数栈深度的最大值。

max_locals局部变量表所需的存储空间。

code_length和code用来存储Java源程序编译后生成的字节码长度和指令。

每个指令占u1类型的单字节,u1类型的取值范围是0x00~0xFF,对应十进制0~255,就是一共可以表达256条指令。
code_length虽然是一共u4类型的长度值,但虚拟机规范中限制了一个方法不允许超过65535条字节码指令,实际上它只使用了u2的长度。

字节码指令之后的是这个方法的显示异常处理表集合。它不是必须存在的。

异常表格式如下图所示:

属性表结构

异常表实际上是Java代码的一部分,编译器使用异常表而不是简单的跳转命令来实现Java异常及finally处理机制。

下图是一段演示异常表如何运作的例子。

 

public int inc(){
        
        int x;
        try {
            x = 1;
            return x;
        } catch (Exception e){
            x = 2;
            return x;
        } finally {
            x = 3;
        }
    }

结合下面两个图看:

编译后的ByteCode字节码

编译后的异常表

下面是对字节码的执行过程的分析:

字节码0~34行所做的操作就是将整数1赋值给变量x,并且将此时x的值复制一份副本到最后一个本地变量表的Slot中。如果没有异常出现,会继续走5~9行,将变量x赋值为3,之前保存的Slot的整数1读入到操作栈顶,最后Slot指令会以int形式返回栈顶中的值,方法结束。如果出现了异常,PC寄存器指针转到第10行,第10~20行是将2赋值给变量x,然后将变量x此时的值给Slot,最后在将变量x的值改为3。方法返回前同样将Slot中保留的整数2读到了栈顶。第21行开始,是变量x的值赋为3,并将栈顶的异常抛出,方法结束。

2.Exceptions属性

与前面异常不一样,Exceptions属性的作用是列举出方法中可能抛出的受检查异常。也就是方法描述时在throws关键字后面列举的异常。结构如下表:

属性表结构

3.LineNumberTable属性

它用于描述Java源码行号与字节码行号(字节码的偏移量)之间的对应关系。可以在Javac中分别使用-g:none或-g:lines选项来取消或要求生成这项信息。如果取消生成,程序运行产生异常时,堆栈中不会显示出错的行号;调试的时候也无法按照源码行设置断点。结构如下:

LineNumberTable属性结构

4.LocalVariableTable属性

它用于描述栈帧中局部便链表的变量与Java源码中定义的变量之间的关系。可以在Javac中分别使用-g:none或-g:vars选项取消或要求生成这项信息。如果没有生成,当其他人引用这个方法时,所有的参数名称都会丢失。,IDE将会使用arg0,arg1之类的占位符代替原有的参数名。结构表如下:

LocalVariableTable属性结构

其中,local_variable_info项目代表了栈帧与源码中的局部变量的关联,结构表如下:

local_variable_info项目结构

JDK1.5引入范型后,增加了一个LocalVariableTypeTable属性,它和LocalVariableTable类似,仅仅是把记录的字段描述符descriptor_index替换成了字段的特征签名。对于非泛型类型来说,描述符和特征签名描述的信息基本一致,泛型引入后,描述符中泛型的参数化类型被擦除,描述符就不能准确的描述泛型类型了,因此出现了LocalVariableTypeTable。

5.SourceFile属性

用于记录生成这个Class文件的源码文件名称。结构表如下:

SourceFile属性结构

6.Constantvalue属性

作用是通知虚拟机自动为静态变量赋值。对于非static类型的变量的赋值是在实例构造器<init>方法中进行的;而对于类变量,有两种方式:1.在类构造器<clinit>方法中;2.使用ConstantValue属性。结构表如下:

ConstantValue属性结构

7.InnerClass属性

用于记录内部类与宿主类之间的关联。结构表如下:

InnerClass属性结构

其中inner_classes_info表的结构如下:

inner_classes_info表的结构

inner_name_index指向常量池中的CONSTANT_Utf8_info型常量的索引,代表这个内部类的名称,如果是匿名内部类,则这项值为0。

inner_class_access_flags是内部类的访问标志,类似于类的access_flags,取值范围如下:

inner_class_access_flags标志

8.Deprecated及Synthetic属性

两个属性都属于标志类型的布尔属性,Deprecated用于表示某个类、字段或方法,被程序作者定为不推荐使用;Synthetic代表此字段或者方法并不是由Java源码直接产生的。他们的结构表如下:

Deprecated及Synthetic属性的结构

9.StackMapTable属性

是一个复杂的变长属性,它会在虚拟机类加载的字节码验证阶段被新类型检查验证器使用,目的是代替以前笔记消耗性能的基于数据流分析的类型推导验证器。结构表如下:

StackMapTable属性结构

10.Signature属性

JDK1.5后增加到Class文件规范中,它是一个可选的定长属性,可以出现在类、属性表和方法表结构的属性表中。任何类、接口、初始化方法或成员的泛型签名如果包含了类型变量或参数化类型,则Signature属性会为它记录泛型签名信息。

之所以用专门的属性记录泛型类型,因为Java的泛型采用的是擦除法实现的伪泛型,在字节码中,泛型信息编译(类型变量、参数化类型)后都被擦除掉。结构表如下:

Signature属性的结构

11.BootstrapMethod属性

在JDK1.7发布后增加到了Class文件规范中,它是一个复杂的变长属性,位于类文件的属性表中,它保存了invokedynamic指令引用的引导方法限定符。结构表如下:

BootstrapMethods属性结构

其中bootstrap_method属性结构表如下:

bootstrap_method属性结构

4.字节码指令简介

Java虚拟机的指令由一个字节长度的、代表某种特定操作含义的数字(操作码)以及跟随其后的0个或者多个代表此操作所需参数(操作数)构成。由于Java虚拟机采用面向操作数栈而不是寄存器的加够,所以大多数的指令都不包含操作数。

字节码指令集:由于Java虚拟机操作码的长度为一个字节,所以指令集的操作码总数不能超过256条;Class文件格式放弃了编译后代码的操作数长度对齐,所以虚拟机处理那些超过一个字节数据的时候,需要重建出具体数据的结构。

例如将一个16位长度的无符号整数使用两个无符号字节存储起来,值是:

(byte1 << 8) | byte2

这种操作会导致解释执行字节码时损失一些性能。好处是它放弃了操作数长度对齐,意味着可以省略很多填充和间隔符号;用一个字节代表操作码,可以尽可能获得短小精干的编译代码。

下面是Java虚拟机解释器的伪代码:

伪代码

4.1 字节码与数据类型

大多数的指令都包含了其操作对应的数据类型信息。礼服iload指令用于从局部变量表中加载int型的数据到操作数栈中,而fload指令加载的是float类型的数据。但是这两条指令在虚拟机内部可能是同一段代码来实现的,只不过它们必须拥有独立的操作码。

4.2 加载和存储指令

加载和存储指令用于将数据在栈帧中的局部变量表和操作数栈之间来回传输。这类指令包括如下内容:

  • 将一个局部变量加载到操作栈:iload、i load<n>、lload、lload<n>、fload、fload<n>、dload、dload<n>、aload、aload<n>。

  • 将一个数值从操作数栈存储到局部变量表:istore、istore<n>、lstore、lstore<n>、fstore、fstore<n>、dstore、dstore<n>、astore、astore<n>。

  • 将一个常量加载到操作数栈:bipush、sipush、ldc、ldc_w、ldc2_w、aconst_null、iconst_m1、iconst_<i>、lconst_<l>、fconst_<f>、dconst_<d>。

  • 扩充局部变量表到访问索引的指令:wide。

4.3 运算指令

运算指令用于对两个操作数栈上的值进行特定运算,并把结果重新存入到操作栈顶。

大体上分两种:整型数据进行运算的指令和浮点型数据运算的指令。无论哪种,都没有直接支持byte、short、char、boolean类型的算术指令,它们都使用操作int类型的指令代替。

4.4 类型转换指令

可以将两种不同的数值类型进行相互转换,这些转换操作一般用于实现用户代码中的显式类型转换操作,或者用来处理字节码指令集中数据类型相关指令无法与数据类型一一对应的问题。

4.5 对象创建与访问指令

  • 创建类实例的指令:new。

  • 创建数组的指令:newarray、anewarray、multianewarrary

  • 访问类字段(static字段)和实例字段(非static字段)的指令:getfield、putfield、getstatic、putstatic。

  • 把一个数组元素加载到操作数栈的指令:baload、caload、saload、iaload、laload、faload、daload、aaload。

  • 将一个操作数栈的值存储到数组元素中的指令:bastore、castore、sastore、iastore、fastore、dastore、aastore。

  • 取数组长度的指令:arraylength。

  • 检查类实例类型的指令:instanceof、checkcast。

4.6 操作数栈管理指令

如同操作一个普通数据结构中的堆栈那样。

4.7 控制转移指令

让Java虚拟机有条件或无条件地从指定的位置指令继续执行程序,而不是从控制转移指令的下一条继续执行,概念模型上说,控制转移指令就是在有条件或无条件地修改PC寄存器的值。

4.8 方法调用和返回指令

方法调用:分派、执行过程第8章详解。

4.9 异常处理指令

4.10 同步指令

Java虚拟机可以支持方法级的同步和方法内部一段指令序列的同步,这两种同步都是使用管程支持。

方法级的同步是隐式的,即无须通过字节码指令来控制,它实现方法调用和返回操作之中。虚拟机可以从方法常量池的方法表结构中的ACC_SYNCHRONIZED访问标志得知一个方法是否声明为同步方法。如果被设置了,执行线程就会先持有管程,方法完成(无论是正常完成还是非正常完成)时释放管程。在方法执行期间,其他任何线程无法再获取同一个管程。

正确实现synchronized关键字需要Javac编译器与Java虚拟机两者共同协作支持。譬如如下代码:

 

void onlyMe (Foo f) {
        synchronized (f){
            doSomething();
        }
    }

编译后,字节码序列如下:

字节码序列

5.公有设计与私有实现

只要符合Java虚拟机规范,虚拟机以任何方式实现这些定义都是可以的,虚拟机后台如何处理Class文件完全是实现者自己的事情,只要它在外部接口上看起来与规范描述的一致。

 

如果本文对你有一点点的帮助,请点个赞呗,谢谢~

最后,若有不足或者不正之处,欢迎指正批评,感激不尽!如果有疑问欢迎留言,绝对第一时间回复!

文字来自优快云:白衣染霜陈——SingIT 整理发布转载请注明出处,谢谢。

路漫漫其修远兮,吾将上下而求索。——白衣

Java领域JVM的类文件结构剖析 本文旨在全面解析Java类文件的二进制结构,帮助开发者深入理解Java程序在JVM中的表示形式。内容涵盖类文件各个组成部分的详细解析,包括其数据结构、编码方式和相互关联。文章首先介绍类文件的基本概念,然后逐部分解析类文件结构,接着通过实际案例演示如何解析类文件,最后讨论相关工具和应用场景。JVM:Java虚拟机,执行Java字节码的运行时环境字节码:JVM执行的指令集,介于源代码和机器码之间常量池:类文件中存储字面量和符号引用的表结构模块化系统:Java 9引入的模块化系统对类文件格式有新的要求。 阅读详情

相关推荐

深入理解 JVM 的栈帧结构

栈帧是运行时数据区中用于支持虚拟机进行方法调用和方法执行的数据结构。每一个方法从调用开始到执行完成,都对应着一个栈帧在虚拟机栈/本地方法栈里从入栈到出栈的过程。 Java 的源码文件经过编译器编译后会生成字节码文件,然后由 JVM 的类加载器进行加载,再交给执行引擎执行。在执行过程中,JVM 会划出一块内存空间来存储程序执行期间所需要用到的数据,这块空间一般被称为运行时数据区。 栈帧(Stack Frame)是运行时数据区中用于支持虚拟机进行方法调用和方法执行的数据结构。每一个方法从调用开始到执行完成

在技术的广袤天地里,本博客如精准罗盘。剖析前沿科技,深掘代码奥秘,以精炼笔触,带您穿越复杂技术迷宫,速达知识彼岸。 1398

JVM笔记9-Class类文件结构

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

weixin_33755847的博客 301

【深入理解JVM】:Class类文件结构

概述我们平时在DOS界面中往往需要运行先运行javac命令,这个命令的直接结果就是产生相应的class文件,然后基于这个class文件才可以真正运行程序得到结果。自然。这是Java虚拟机的功劳,那么是不是Java虚拟机只能编译.java的源文件呢?答案是否定的。时至今日,Java虚拟机已经实现了语言无关性的特点。而实现语言无关性的基础是虚拟机和字节码的存储格式,Java虚拟机已经不和包括Java语言

smile4lee的博客 4069

Java类文件结构

本文系统介绍了Java字节码与Class文件结构。主要内容包括:1. 字节码作为平台无关性的基石,支持多种语言特性;2. Class文件采用紧凑的二进制流存储,包含魔数、版本号、常量池等结构;3. 详细解析了访问标志、类继承关系、字段表、方法表等核心组成部分;4. 重点分析了Code属性、异常处理、同步机制等关键特性;5. 介绍了字节码指令集及其分类(运算、控制转移、方法调用等);6. 阐述了JVM实现方式的灵活性,包括解释执行和JIT编译两种途径。文章全面展示了Class文件如何实现Java"一

纯洁的小魔鬼 2331

测试dali协议的软件,DALI2.0和DALI1.0完美兼容同一个模块,测试每项可过协议

DALI2.0和DALI1.0完美兼容同一个模块,测试每项可过协议深圳聚积智能 夏先生 13246760327 QQ 349098308■IEC62386-102(V2.0)通过测试内容IEC62386-102/2.1/Test preambleIEC62386-102/3.1/Polarity testIEC62386-102/3.2/Maximum and minimum system v...

weixin_35343788的博客 1351

grpc安装与简单demo测试

grpc安装: 由于工作需要,最近在学google的rpc开源框架;由于本人菜鸟一枚,而且是从Windows开发转到Linux;由于之前版本控制使用的是svn,没有使用过git,所以从GitHub上下载代码是通过浏览器下载zip格式的压缩文件,折腾了好几天了,发现了各种坑,各种缺少库,各种不知道怎么把这个库给装机器上。对于一个不熟悉Linux的人来说,这个体验简直糟糕透了。没办法了又在机器上装了...

old__captain的博客 4833

JVM高级特性与实践(六):Class类文件的结构(访问标志,索引、字段表、方法表、属性表集合)

代码编译的结果从本地机器码转变为字节码,是存储格式发展的一小步,却是编译发展的一大步。 上篇博文中学习讲解了Class类文件结构的有关知识点,关于数据项方面介绍了常量池,此篇文章将介绍完余下的数据项部分,大致知识点如下: 访问标志、类索引、父类索引与接口索引集合、字段表集合、属性表集合 、各数据项的定义、作用、结构组成及实例讲解

lemonGuo的大脑皮层、小脑、海马体、杏仁核..... 3328

python采集keep运动数据

我国2009年确立“全民健身日”;2012年,“广泛开展全民健身运动”写入十八大报告;到2014年上升为国家战略,全民健身的分量越来越重。推动全民健身和全民健康深度融合,通过全民健身实现全民健康。 全民健身运动在我国越来越普及,每天清晨和傍晚时分,城市的广场上、公园里,到处是运动健身的人们,跑步、打球、跳舞、游泳、打太极拳等运动项目十分丰富,人们在运动中获得越来越多的幸福感。 随之诞生出了很多运动app,例如keep,咪咕,微信等,大家可以通过app随时记录自己的运动数据,特别是对于很多的减肥人群来说,通过

Z_suger7的博客 5657

一-Class文件结构

1.1 概述 Java规范 BAT面试题 类文件结构有几个部分? 字节码都有哪些?Integer x = 5 ;int y = 5;比较x==y都经过了哪些步骤 public class IntegerTest { public static void main(String[] args) { Integer i1 = 10; Integer i2 = 10; System.out.println(i1 == i2);//true

u014215131的博客 582

012、乘累加单元(MAC):NPU中最基本的计算单元

本文深入剖析了神经网络处理器(NPU)中的核心计算单元——乘累加单元(MAC)。作者通过实际调试案例揭示了MAC单元设计中的关键问题:定点数格式对齐、累加器位宽陷阱、流水线优化和多MAC同步方案。重点讨论了INT8量化中的边界条件处理、偏置项截断风险以及零值检测等实战经验,并提供了三点实用建议:建立精确的C模型、参考RISC-V P扩展指令集、仔细审查芯片规格书。文章强调硬件加速的实际瓶颈往往在于数据搬运而非计算单元本身,为NPU开发者提供了宝贵的工程实践参考。

m0_50546716的博客 298

前程无忧Python岗位数据采集:基于API直连的高效招聘信息爬取实战

本文介绍了一个基于Python requests库的前程无忧招聘数据采集系统。项目通过分析API接口结构,配置完整的请求头和身份验证参数,实现了高效稳定的数据采集。系统支持多页数据批量获取,包含工作名称、薪资范围等关键字段的结构化解析,并将结果存储为Excel文件。技术实现涉及API分析、身份验证、请求头配置、数据清洗等关键步骤,同时强调遵守法律和道德规范。该系统可为求职者、HR和市场分析师提供有价值的行业数据支持,适用于市场分析、职业规划等场景。

那些看似不起波澜的日复一日,会在某天让你看到坚持的意义 1552

Bootstrap Method

bootstrap方法是一种重采样技术,用于通过抽样数据集来估计总体统计数据。是一种面向应用的、基于大量计算的统计思维——模拟抽样统计推断。 它可以用来估计统计数据,例如平均值或标准差。在应用机器学习中,当对不包含在训练数据中的数据进行预测时,它用于评估机器学习模型的技能。 评估机器学习模型技能结果特的点是,估计方法可以用置信区间来表示,这是其他方法不容易得到的,比如交叉验证。 B...

weixin_30535565的博客 454

【AI Agent】Hermes Agent解析

Hermes Agent:一个具备持久化学习能力的开源AI Agent框架 核心特点: 突破传统Agent的"无状态困境",通过记忆系统(SQLite+FTS5全文检索)实现跨会话经验积累 支持200+模型自由切换,11种模型家族和15+平台接入 五层架构设计(入口层、编排层、推理层、工具执行层、存储层)实现平台无关性 47+内置工具和动态技能沉淀机制,支持从任务执行中自动提炼可复用Skill 独特的四层记忆体系(会话/每日/长期/向量索引)和辩证式用户建模 与传统Agent对比: 具备自我进化能力,通过A

sysu_lluozh 940

深入理解JVM - 类文件结构

深入理解JVM - 类文件结构 前言 ​ JVM的类文件结构基本都会要记忆的内容,我相信你也记不住,当然我也是记不住的,所以这里只会列出大致的类文件结构,我们需要大致了解类文件结构是怎么一回事就行了,具体到那个位存哪个内容,内容确实太多了,感兴趣可以直接去读书中对应的第6章 类文件结构这一个章节的内容。 ​ 类文件结构个人认为需要注意的点就是这几点:大致的类文件结构,部分Jdk的特性如何通过改动class文件结构实现,比如泛型,自动拆装箱,动态代{过}{滤}理,lambada语法等。 概述: ​ 其实主要内

SharenFish的博客 1663

(11-3-03)多任务与元强化学习:综合实战:基于元强化学习的迷宫导航系统(3)

本文介绍了策略网络隐空间可视化的实现方法及其在强化学习中的应用。通过设计visualize_latent_space函数,使用t-SNE算法将高维隐空间特征降维至二维进行可视化,直观展示策略网络在不同任务中的特征分布。文章详细阐述了实现流程:状态收集、t-SNE降维和可视化绘图,并提供了完整的Python代码示例。实验结果表明,该方法能有效分析策略网络的学习过程与适应能力,为优化模型提供重要依据。同时,文章还介绍了主程序的完整流程,包括环境初始化、元智能体训练与评估、学习策略比较等环节,最后对实验结果进行可

码农三叔 1041

SAP ABAP Append structure 介绍

所有在 append structure 上增强的字段都是 append structure 的一部分,这意味着对这些增强所做的任何更改仅仅施加在 append structure 上,而不会影响被增强的 ABAP DDIC 结构。这同样适用于 transport. 激活数据库表或结构时,会找到所有关联的 append structure,并将它们的组件附加到数据库表或结构。Append structure(附加结构)是 ABAP 字典中附加到另一个结构或数据库表并将其组件附加到它们的结构。

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 1165

深入理解JVM - 阅读笔记之思维导图 - 目录

深入理解JVM - 阅读笔记之思维导图阅读前须知目录总图 阅读前须知 本博客的主要作用是记录我在阅读《深入理解Java虚拟机》(周志明著)时的一些阅读笔记,此笔记是采用思维导图的形式记录的,较原书而言较为精简,但可能存在一些错误,如果有错误请在评论区指出,我会尽快修改。 在本思维导图中,会看到一个如下图所示的一个小记号,代表笔记/注释,在对应章节的底部我会列出来关于这个笔记/注释的一些具体信息。 ...

timczm的博客 5624

IEM模型,地表粗糙度模拟

利用微波反演土壤水分时候,利用IEM模型可以实现对随机地表的模拟

JVM—类文件结构

Class文件是一组以字节为基础单位的二进制流,各个数据项目严格按照顺序排列紧凑的在文件中,中间没有任何分隔符。Class文件采用一种类似于C语言结构体的伪结构来存储数据,这种伪结构只有“无符号数”和“表”两种数据类型无符号数:属于基本数据类型,以u1、u2、u4、u8分别表示1个字节,2个字节...这样。可以用来描述索引引用、数字、数量值等。表:是由多个无符号数或者其他表作为数据项构成的有层次关系的复合数据类型,一般以_info结尾,整个Class本质上也可以视作一张表。

摸鱼小小虫的博客 1137

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

JVM类文件结构深度解析:跨平台基石与字节码探秘

类文件是Java生态的通用中间表示,其精巧设计体现了计算机科学中抽象与实现的完美平衡。掌握这一结构,是我们开发者通向高级Java开发的必经之路!

m0_73804764的博客 1159

VC中sqlite的使用

在VC中对sqlite的使用,实现数据库大批数据的快速插入,读取数据库中的数据在ListCtrl中显示

JVM-Class类文件结构笔记

JVM-Class类文件结构速成,基于《深入理解Java虚拟机:JVM高级特性与最佳实践(第3版)》第6章

m0_52133525的博客 224

深入理解JVM-类文件结构

你未必出类拔萃,但一定与众不同 类文件结构 文章目录类文件结构概述Class类文件的结构魔数与Class文件的版本常量池访问标志类索引,父类索引和接口索引集合字段表集合方法表集合属性表集合 概述 由于最近十年内虚拟机以及大量建立在虚拟机之上的程序语言如雨后春笋一般出现,把我们编写的程序编译成二进制本地机器码已经不在是唯一选择 越来越多的语言选择了与操作系统和机器指令集无关的格式作为编译后的存储格式 Java语言中的各种语法,关键字,。常量变量和运算符号的语义最终都会由多条字节码指令组合来表达。 Cla.

qq_44752800的博客 1147

JVM——》类文件

JVM——》类文件

小仙~ 189

深入理解Java虚拟机:Jvm总结-类文件结构以及类加载机制

代码编译的结果从本地机器码转变为字节码,冲破了平台界限。

Oceáno的博客 1496

深入理解类文件结构

字节码是一种介于源代码和机器码之间的中间代码,它不是特定硬件架构的机器指令,而是一种与平台无关的、抽象的指令集,主要用于实现程序的跨平台运行。

2201_75450136的博客 1102

JVM类文件结构详解-使用字节码解读

详解Java类文件结构,使用字节码二进制流一一解读,取自【深入理解JVM虚拟机】-周志明

qq_52107150的博客 892
上一篇: 5.网络七层协议以及应用
下一篇: 2018——颓废的一年,勿忘初心。
白衣染霜陈
博客等级 码龄22年 682粉丝 338原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值