HotSpot虚拟机之Class文件及字节码指令

目录

一、javac编译

1. 编译过程

2. 语法糖 

二、Class文件

1. 文件格式 

2. 常量池项目

3.  属性类型

三、Class文件实例

1. 源代码

2. javap分析Class文件

四、字节码指令

五、参考资料


一、javac编译

1. 编译过程

        javac命令由Java语言编写,目的将Java源码转变成字节码(只完成源码到抽象语法树或字节码的生成),JDK12源码其运行入口是com.sun.tools.javac.Main#main。javac主体代码如下图所示。com.sun.tools.javac.main.JavaCompiler#compile核心方法。

        javac编译过程:一个准备(初始化插入式注解处理器);三个处理(解析与填充符号表、处理注解处理器、语义分析与字节码生成),如下图所示。

        需要注意的是:生成<init>()、<clinit>()方法在编译期完成;Lombok操作通过插入式注解处理器完成对字段的getter()和setter()方法

2. 语法糖 

二、Class文件

1. 文件格式 

        Class文件是字节为单位的二进制流,有两种数据类型:无符号数、表,如下图所示。Class文件不保存方法、字段最终的内存布局信息,JVM运行期才能找到内存入口地址

        Class文件格式如下表所示,主要有:常量池、字段表、方法表、属性表等。Class文件可以使用十六进制编辑器WinHex打开。注意:常量池(constant_pool)的数量是constant_pool_count减1,若为0说明“不引用任何常量池项目”;而其他表从0开始计数。

数据类型

名称

数量

作用及特点

u4

magic

1

1.魔数:确定文件是否是Class文件;

2.固定值:0xCAFEBABE

u2

minnor_version

1

次版本

u2

major_version

1

1.版本号;

2.JDK向前兼容老版本,则不能向后兼容新版本。

u2

constant_pool_count

1

1.常量池容量计数数量;

2.索引从1开始,其他表从0开始

3.若为0,则说明不引用任何常量池项目

cp_info

constant_pool

constant_pool_count

 - 1

1.常量池,有两大类常量:字面量、符号引用

2.17种不同类型常量,如:

   CONSTANT_Utf8_info、  

   CONSTANT_Class_info

   CONSTANT_Fieldref_info   

   CONSTANT_Methodref_info......

u2

access_flags

1

1.类或接口的访问修饰符;

2.如:ACC_PUBLIC(是否为public修饰)。

u2

this_class

1

类索引:当前类的全限定名

u2

super_class

1

1.父类索引:当前类的父类的全限定名;

2.java.lang.Object外,所有类的父类值都不为0

u2

interfaces_count

1

1.接口索引的数量;

2.没有实现任何接口时,该值为0

u2

interfaces

interfaces_count

1.接口索引:当前类的所有接口的全限定名;

2.接口从左往右的顺序在该表中

u2

fields_count

1

类或接口的字段数量

field_info

fields

fields_count

1.类或接口的字段(实例变量,类变量);

2.不包括:方法内局部变量;

3.内容有:修饰符、在常量池中索引、简单名称、描述符、属性表(attribute_info;

4.描述符:字段的数据类型、方法的参数列表及返回值

5.不会列出父类或接口的字段

6.可能含有JVM自动生成的字段,如:this字段

u2

methods_count

1

类或接口的方法数量

method_info

methods

methods_count

1.类或接口的方法(实例方法,类方法);

2.内容有:修饰符、在常量池中索引、简单名称、描述符、属性表(attribute_infoCode;

3.“描述符:字段的数据类型、方法的参数列表及返回值

4.不会列出父类或接口的方法(重写除外)

5.可能含有JVM自动生成的方法,如:<init>()<cinit>()方法

u2

attributes_count

1

属性表数量

attribute_info

attributes

attributes_count

1.Class文件、字段、方法都有自己的属性;

2.属性只要不重名,任何编译器都可以添加自己的属性信息

2. 常量池项目

        常量池有两大类常量:字面量、符号引用。当类加载时,从常量池获得对应的符号引用,再在类创建或运行解析时,翻译到具体的内存地址中。如下表所示是17种不同类型的常量。

        “描述符”作用是描述字段的数据类型、方法的参数列表(包括:数量、类型、顺序)、返回值。数组类型,每一个维度用前置的“[”标识,如:void inc(int[ ] ints)其描述符为([I)V。下表所示是描述符标识字符含义。

3.  属性类型

        Class文件、字段、方法都有自己的属性,这些属性存储到属性表(attribute_info),《Java虚拟机规范》允许属性只要不重名,任何编译器都可以添加自己的属性信息。

        如下表所示是常用属性介绍,其中整个Class文件中,只有Code属性描述方法体的代码,其他所有数据项目都是描述元数据

常用属性

使用位置

含义

Code

方法表

1.作用:描述方法体代码,注意:不是所有方法都有Code属性,如:接口、抽象类的方法等;

2.Code属性表中常用参数:

  max_stack:操作数栈的最大深度;

  max_locals:局部变量表的最大slot数量(不是空间大小);

  args_size:方法的参数数量,注意:若实例方法,则有this参数;

  code:方法体的字节码指令流;

  .....

LineNumberTable

Code属性

1.源码行号与字节码指令行的对应关系;

2.字节码指令的“行”:是相对于方法体开始的偏移量。

LocalVariableTable

Code属性

1.方法的局部变量描述;

2.注意:若实例方法,则有this参数;

3.结构中:start_pc(变量开始的字节码偏移量) + length(长度)决定变量的作用域。

StackMapTable

Code属性

1.目的:类加载时字节码验证阶段进行类型检查(新类型检查器);

2.含义:0或多个栈映射帧(代表字节码偏移量),即:执行到该字节码时局部变量表和操作数栈的验证类型。

ConstantValue

字段表

1.常量值:为static修饰的变量赋值的值;

2.常量值只能是:基本数据类型、String。

Exceptions

方法表

方法抛出的异常列表 

InnerClasses

类文件

内部类列表

Signature

类、方法表、

字段表

1.记录泛型签名信息,如:类型变量、类型参数等;

2.反射API就是根据这个属性来获取泛型信息。

MethodParameters

方法表

记录方法的各个形参和信息

Synthetic

类、方法表、

字段表

1.标识方法或字段是编译器自动生成,至少有Synthetic或ACC_SYNTHETIC一个;

2.如:实例构造器<init>()、类构造器<cinit>();

其他:Deprecated(含有@Deprecated)、EnclosingMethod(含有局部类或匿名类)、

           RuntimeVisibleAnnotations(运行时可见的注解,反射可调用)、SourceFile(记录源文件名称)、

           RuntimeInvisibleAnnotations(运行时不可见的注解,反射不可调用)、

           AnnotationDefault(含有注解类元素默认值)、Modlue(记录模块信息)、

           BootstrapMethods(保存invokedynamic指令引用的引导方法限定符)、

           ......

三、Class文件实例

1. 源代码

        如下代码,用javac编译成Class文件。

package com.common.instance.demo.core.serviceLevel;import com.alibaba.fastjson.JSON;
import com.log.util.LogUtil;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.stereotype.Component;import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.*;/*** @description 一级业务线程池处理业务* @author tcm* @version 1.0.0* @date 2021/9/29 16:01**/
@Component
public class OneLevelAsyncContext implements InitializingBean {private final String URI = "uri";private final String PARAMS = "params";private AsyncListener asyncListener;private LinkedBlockingDeque<Runnable> queue;private ThreadPoolExecutor executor;public Object submitFuture(final HttpServletRequest request, final Callable<Object> task) throws ExecutionException, InterruptedException {// 获取请求URIfinal String uri = request.getRequestURI();// 获取请求参数final Map<String, String[]> params = request.getParameterMap();// 开启异步上下文final AsyncContext asyncContext = request.startAsync();asyncContext.getRequest().setAttribute(URI, uri);asyncContext.getRequest().setAttribute(PARAMS, params);// 超时设置asyncContext.setTimeout(2 * 1000);if (Objects.nonNull(asyncListener)) {asyncContext.addListener(this.asyncListener);}// 线程池处理业务Future<Object> future = executor.submit(new Callable<Object>() {@Overridepublic Object call() throws Exception {// 业务处理Object result = task.call();return result;}});// 完成异步上下文,否则报超时等异常asyncContext.complete();return future.get();}// 完成初始化配置@Overridepublic void afterPropertiesSet() throws Exception {// 线程池大小int corePoolSize = Integer.parseInt("100");// 最大线程池大小int maxNumPoolSize = Integer.parseInt("200");// 任务队列queue = new LinkedBlockingDeque<Runnable>();// 创建线程池executor = new ThreadPoolExecutor(corePoolSize, maxNumPoolSize, 100, TimeUnit.MILLISECONDS, queue);executor.allowCoreThreadTimeOut(true);// 线程池饱和处理executor.setRejectedExecutionHandler(new RejectedExecutionHandler() {@Overridepublic void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {if (r instanceof CanceledCallable) {CanceledCallable cc = ((CanceledCallable) r);AsyncContext asyncContext = cc.asyncContext;try {ServletRequest request = asyncContext.getRequest();String uri = (String) request.getAttribute(URI);Map params = (Map) request.getAttribute(PARAMS);LogUtil.error(String.format("async request %s, uri:%s, params:%s", "rejectedExecution", uri, JSON.toJSONString(params)));} catch (Exception ex) {}try {HttpServletResponse response = (HttpServletResponse) asyncContext.getResponse();response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);} finally {asyncContext.complete();}}}});// 创建监听器if (Objects.isNull(asyncListener)) {asyncListener = new AsyncListener() {@Overridepublic void onComplete(AsyncEvent asyncEvent) throws IOException {}@Overridepublic void onTimeout(AsyncEvent asyncEvent) throws IOException {AsyncContext asyncContext = asyncEvent.getAsyncContext();try {ServletRequest request = asyncContext.getRequest();String uri = (String) request.getAttribute(URI);Map params = (Map) request.getAttribute(PARAMS);LogUtil.error(String.format("async request timeout, uri:%s, params:%s", uri, JSON.toJSONString(params)));} catch (Exception e) {}try {HttpServletResponse resp = (HttpServletResponse) asyncContext.getResponse();resp.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);} finally {asyncContext.complete();}}@Overridepublic void onError(AsyncEvent asyncEvent) throws IOException {AsyncContext asyncContext = asyncEvent.getAsyncContext();try {ServletRequest request = asyncContext.getRequest();String uri = (String) request.getAttribute(URI);Map params = (Map) request.getAttribute(PARAMS);LogUtil.error(String.format("async request error, uri:%s, params:%s", uri, JSON.toJSONString(params)));} catch (Exception e) {}try {HttpServletResponse resp = (HttpServletResponse) asyncContext.getResponse();resp.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);} finally {asyncContext.complete();}}@Overridepublic void onStartAsync(AsyncEvent asyncEvent) throws IOException {}};}}}

2. javap分析Class文件

        javap命令分析Class文件,如:javap -verbose OneLevelAsyncContext.class,代码所示。

Classfile /E:/Idea Project/instance-demo/target/classes/com/common/instance/demo/core/serviceLevel/OneLevelAsyncContext.classLast modified 2023-7-22; size 4120 bytesMD5 checksum ab1d73e3259040031896505e9ed1e1bbCompiled from "OneLevelAsyncContext.java"
public class com.common.instance.demo.core.serviceLevel.OneLevelAsyncContext implements org.springframework.beans.factory.InitializingBeanminor version: 0major version: 52flags: ACC_PUBLIC, ACC_SUPER
Constant pool:#1 = Methodref          #42.#99       // java/lang/Object."<init>":()V#2 = String             #70           // uri#3 = Fieldref           #10.#100      // com/common/instance/demo/core/serviceLevel/OneLevelAsyncContext.URI:Ljava/lang/String;#4 = String             #71           // params#5 = Fieldref           #10.#101      // com/common/instance/demo/core/serviceLevel/OneLevelAsyncContext.PARAMS:Ljava/lang/String;#6 = InterfaceMethodref #102.#103     // javax/servlet/http/HttpServletRequest.getRequestURI:()Ljava/lang/String;#7 = InterfaceMethodref #102.#104     // javax/servlet/http/HttpServletRequest.getParameterMap:()Ljava/util/Map;#8 = InterfaceMethodref #102.#105     // javax/servlet/http/HttpServletRequest.startAsync:()Ljavax/servlet/AsyncContext;#9 = InterfaceMethodref #106.#107     // javax/servlet/AsyncContext.getRequest:()Ljavax/servlet/ServletRequest;#10 = Class              #108          // com/common/instance/demo/core/serviceLevel/OneLevelAsyncContext#11 = InterfaceMethodref #109.#110     // javax/servlet/ServletRequest.setAttribute:(Ljava/lang/String;Ljava/lang/Object;)V#12 = Long               2000l#14 = InterfaceMethodref #106.#111     // javax/servlet/AsyncContext.setTimeout:(J)V#15 = Fieldref           #10.#112      // com/common/instance/demo/core/serviceLevel/OneLevelAsyncContext.asyncListener:Ljavax/servlet/AsyncListener;#16 = Methodref          #113.#114     // java/util/Objects.nonNull:(Ljava/lang/Object;)Z#17 = InterfaceMethodref #106.#115     // javax/servlet/AsyncContext.addListener:(Ljavax/servlet/AsyncListener;)V#18 = Fieldref           #10.#116      // com/common/instance/demo/core/serviceLevel/OneLevelAsyncContext.executor:Ljava/util/concurrent/ThreadPoolExecutor;#19 = Class              #117          // com/common/instance/demo/core/serviceLevel/OneLevelAsyncContext$1#20 = Methodref          #19.#118      // com/common/instance/demo/core/serviceLevel/OneLevelAsyncContext$1."<init>":(Lcom/common/instance/demo/core/serviceLevel/OneLevelAsyncContext;Ljava/util/concurrent/Callable;)V#21 = Methodref          #30.#119      // java/util/concurrent/ThreadPoolExecutor.submit:(Ljava/util/concurrent/Callable;)Ljava/util/concurrent/Future;#22 = InterfaceMethodref #106.#120     // javax/servlet/AsyncContext.complete:()V#23 = InterfaceMethodref #121.#122     // java/util/concurrent/Future.get:()Ljava/lang/Object;#24 = String             #123          // 100#25 = Methodref          #124.#125     // java/lang/Integer.parseInt:(Ljava/lang/String;)I#26 = String             #126          // 200#27 = Class              #127          // java/util/concurrent/LinkedBlockingDeque#28 = Methodref          #27.#99       // java/util/concurrent/LinkedBlockingDeque."<init>":()V#29 = Fieldref           #10.#128      // com/common/instance/demo/core/serviceLevel/OneLevelAsyncContext.queue:Ljava/util/concurrent/LinkedBlockingDeque;#30 = Class              #129          // java/util/concurrent/ThreadPoolExecutor#31 = Long               100l#33 = Fieldref           #130.#131     // java/util/concurrent/TimeUnit.MILLISECONDS:Ljava/util/concurrent/TimeUnit;#34 = Methodref          #30.#132      // java/util/concurrent/ThreadPoolExecutor."<init>":(IIJLjava/util/concurrent/TimeUnit;Ljava/util/concurrent/BlockingQueue;)V#35 = Methodref          #30.#133      // java/util/concurrent/ThreadPoolExecutor.allowCoreThreadTimeOut:(Z)V#36 = Class              #134          // com/common/instance/demo/core/serviceLevel/OneLevelAsyncContext$2#37 = Methodref          #36.#135      // com/common/instance/demo/core/serviceLevel/OneLevelAsyncContext$2."<init>":(Lcom/common/instance/demo/core/serviceLevel/OneLevelAsyncContext;)V#38 = Methodref          #30.#136      // java/util/concurrent/ThreadPoolExecutor.setRejectedExecutionHandler:(Ljava/util/concurrent/RejectedExecutionHandler;)V#39 = Methodref          #113.#137     // java/util/Objects.isNull:(Ljava/lang/Object;)Z#40 = Class              #138          // com/common/instance/demo/core/serviceLevel/OneLevelAsyncContext$3#41 = Methodref          #40.#135      // com/common/instance/demo/core/serviceLevel/OneLevelAsyncContext$3."<init>":(Lcom/common/instance/demo/core/serviceLevel/OneLevelAsyncContext;)V#42 = Class              #139          // java/lang/Object#43 = Class              #140          // org/springframework/beans/factory/InitializingBean#44 = Utf8               InnerClasses#45 = Utf8               URI#46 = Utf8               Ljava/lang/String;#47 = Utf8               ConstantValue#48 = Utf8               PARAMS#49 = Utf8               asyncListener#50 = Utf8               Ljavax/servlet/AsyncListener;#51 = Utf8               queue#52 = Utf8               Ljava/util/concurrent/LinkedBlockingDeque;#53 = Utf8               Signature#54 = Utf8               Ljava/util/concurrent/LinkedBlockingDeque<Ljava/lang/Runnable;>;#55 = Utf8               executor#56 = Utf8               Ljava/util/concurrent/ThreadPoolExecutor;#57 = Utf8               <init>#58 = Utf8               ()V#59 = Utf8               Code#60 = Utf8               LineNumberTable#61 = Utf8               LocalVariableTable#62 = Utf8               this#63 = Utf8               Lcom/common/instance/demo/core/serviceLevel/OneLevelAsyncContext;#64 = Utf8               submitFuture#65 = Utf8               (Ljavax/servlet/http/HttpServletRequest;Ljava/util/concurrent/Callable;)Ljava/lang/Object;#66 = Utf8               request#67 = Utf8               Ljavax/servlet/http/HttpServletRequest;#68 = Utf8               task#69 = Utf8               Ljava/util/concurrent/Callable;#70 = Utf8               uri#71 = Utf8               params#72 = Utf8               Ljava/util/Map;#73 = Utf8               asyncContext#74 = Utf8               Ljavax/servlet/AsyncContext;#75 = Utf8               future#76 = Utf8               Ljava/util/concurrent/Future;#77 = Utf8               LocalVariableTypeTable#78 = Utf8               Ljava/util/concurrent/Callable<Ljava/lang/Object;>;#79 = Utf8               Ljava/util/Map<Ljava/lang/String;[Ljava/lang/String;>;#80 = Utf8               Ljava/util/concurrent/Future<Ljava/lang/Object;>;#81 = Utf8               StackMapTable#82 = Class              #141          // java/lang/String#83 = Class              #142          // java/util/Map#84 = Class              #143          // javax/servlet/AsyncContext#85 = Utf8               Exceptions#86 = Class              #144          // java/util/concurrent/ExecutionException#87 = Class              #145          // java/lang/InterruptedException#88 = Utf8               MethodParameters#89 = Utf8               (Ljavax/servlet/http/HttpServletRequest;Ljava/util/concurrent/Callable<Ljava/lang/Object;>;)Ljava/lang/Object;#90 = Utf8               afterPropertiesSet#91 = Utf8               corePoolSize#92 = Utf8               I#93 = Utf8               maxNumPoolSize#94 = Class              #146          // java/lang/Exception#95 = Utf8               SourceFile#96 = Utf8               OneLevelAsyncContext.java#97 = Utf8               RuntimeVisibleAnnotations#98 = Utf8               Lorg/springframework/stereotype/Component;#99 = NameAndType        #57:#58       // "<init>":()V#100 = NameAndType        #45:#46       // URI:Ljava/lang/String;#101 = NameAndType        #48:#46       // PARAMS:Ljava/lang/String;#102 = Class              #147          // javax/servlet/http/HttpServletRequest#103 = NameAndType        #148:#149     // getRequestURI:()Ljava/lang/String;#104 = NameAndType        #150:#151     // getParameterMap:()Ljava/util/Map;#105 = NameAndType        #152:#153     // startAsync:()Ljavax/servlet/AsyncContext;#106 = Class              #143          // javax/servlet/AsyncContext#107 = NameAndType        #154:#155     // getRequest:()Ljavax/servlet/ServletRequest;#108 = Utf8               com/common/instance/demo/core/serviceLevel/OneLevelAsyncContext#109 = Class              #156          // javax/servlet/ServletRequest#110 = NameAndType        #157:#158     // setAttribute:(Ljava/lang/String;Ljava/lang/Object;)V#111 = NameAndType        #159:#160     // setTimeout:(J)V#112 = NameAndType        #49:#50       // asyncListener:Ljavax/servlet/AsyncListener;#113 = Class              #161          // java/util/Objects#114 = NameAndType        #162:#163     // nonNull:(Ljava/lang/Object;)Z#115 = NameAndType        #164:#165     // addListener:(Ljavax/servlet/AsyncListener;)V#116 = NameAndType        #55:#56       // executor:Ljava/util/concurrent/ThreadPoolExecutor;#117 = Utf8               com/common/instance/demo/core/serviceLevel/OneLevelAsyncContext$1#118 = NameAndType        #57:#166      // "<init>":(Lcom/common/instance/demo/core/serviceLevel/OneLevelAsyncContext;Ljava/util/concurrent/Callable;)V#119 = NameAndType        #167:#168     // submit:(Ljava/util/concurrent/Callable;)Ljava/util/concurrent/Future;#120 = NameAndType        #169:#58      // complete:()V#121 = Class              #170          // java/util/concurrent/Future#122 = NameAndType        #171:#172     // get:()Ljava/lang/Object;#123 = Utf8               100#124 = Class              #173          // java/lang/Integer#125 = NameAndType        #174:#175     // parseInt:(Ljava/lang/String;)I#126 = Utf8               200#127 = Utf8               java/util/concurrent/LinkedBlockingDeque#128 = NameAndType        #51:#52       // queue:Ljava/util/concurrent/LinkedBlockingDeque;#129 = Utf8               java/util/concurrent/ThreadPoolExecutor#130 = Class              #176          // java/util/concurrent/TimeUnit#131 = NameAndType        #177:#178     // MILLISECONDS:Ljava/util/concurrent/TimeUnit;#132 = NameAndType        #57:#179      // "<init>":(IIJLjava/util/concurrent/TimeUnit;Ljava/util/concurrent/BlockingQueue;)V#133 = NameAndType        #180:#181     // allowCoreThreadTimeOut:(Z)V#134 = Utf8               com/common/instance/demo/core/serviceLevel/OneLevelAsyncContext$2#135 = NameAndType        #57:#182      // "<init>":(Lcom/common/instance/demo/core/serviceLevel/OneLevelAsyncContext;)V#136 = NameAndType        #183:#184     // setRejectedExecutionHandler:(Ljava/util/concurrent/RejectedExecutionHandler;)V#137 = NameAndType        #185:#163     // isNull:(Ljava/lang/Object;)Z#138 = Utf8               com/common/instance/demo/core/serviceLevel/OneLevelAsyncContext$3#139 = Utf8               java/lang/Object#140 = Utf8               org/springframework/beans/factory/InitializingBean#141 = Utf8               java/lang/String#142 = Utf8               java/util/Map#143 = Utf8               javax/servlet/AsyncContext#144 = Utf8               java/util/concurrent/ExecutionException#145 = Utf8               java/lang/InterruptedException#146 = Utf8               java/lang/Exception#147 = Utf8               javax/servlet/http/HttpServletRequest#148 = Utf8               getRequestURI#149 = Utf8               ()Ljava/lang/String;#150 = Utf8               getParameterMap#151 = Utf8               ()Ljava/util/Map;#152 = Utf8               startAsync#153 = Utf8               ()Ljavax/servlet/AsyncContext;#154 = Utf8               getRequest#155 = Utf8               ()Ljavax/servlet/ServletRequest;#156 = Utf8               javax/servlet/ServletRequest#157 = Utf8               setAttribute#158 = Utf8               (Ljava/lang/String;Ljava/lang/Object;)V#159 = Utf8               setTimeout#160 = Utf8               (J)V#161 = Utf8               java/util/Objects#162 = Utf8               nonNull#163 = Utf8               (Ljava/lang/Object;)Z#164 = Utf8               addListener#165 = Utf8               (Ljavax/servlet/AsyncListener;)V#166 = Utf8               (Lcom/common/instance/demo/core/serviceLevel/OneLevelAsyncContext;Ljava/util/concurrent/Callable;)V#167 = Utf8               submit#168 = Utf8               (Ljava/util/concurrent/Callable;)Ljava/util/concurrent/Future;#169 = Utf8               complete#170 = Utf8               java/util/concurrent/Future#171 = Utf8               get#172 = Utf8               ()Ljava/lang/Object;#173 = Utf8               java/lang/Integer#174 = Utf8               parseInt#175 = Utf8               (Ljava/lang/String;)I#176 = Utf8               java/util/concurrent/TimeUnit#177 = Utf8               MILLISECONDS#178 = Utf8               Ljava/util/concurrent/TimeUnit;#179 = Utf8               (IIJLjava/util/concurrent/TimeUnit;Ljava/util/concurrent/BlockingQueue;)V#180 = Utf8               allowCoreThreadTimeOut#181 = Utf8               (Z)V#182 = Utf8               (Lcom/common/instance/demo/core/serviceLevel/OneLevelAsyncContext;)V#183 = Utf8               setRejectedExecutionHandler#184 = Utf8               (Ljava/util/concurrent/RejectedExecutionHandler;)V#185 = Utf8               isNull
{public com.common.instance.demo.core.serviceLevel.OneLevelAsyncContext();descriptor: ()Vflags: ACC_PUBLICCode:stack=2, locals=1, args_size=10: aload_01: invokespecial #1                  // Method java/lang/Object."<init>":()V4: aload_05: ldc           #2                  // String uri7: putfield      #3                  // Field URI:Ljava/lang/String;10: aload_011: ldc           #4                  // String params13: putfield      #5                  // Field PARAMS:Ljava/lang/String;16: returnLineNumberTable:line 23: 0line 25: 4line 26: 10LocalVariableTable:Start  Length  Slot  Name   Signature0      17     0  this   Lcom/common/instance/demo/core/serviceLevel/OneLevelAsyncContext;public java.lang.Object submitFuture(javax.servlet.http.HttpServletRequest, java.util.concurrent.Callable<java.lang.Object>) throws java.util.concurrent.ExecutionException, java.lang.InterruptedException;descriptor: (Ljavax/servlet/http/HttpServletRequest;Ljava/util/concurrent/Callable;)Ljava/lang/Object;flags: ACC_PUBLICCode:stack=5, locals=7, args_size=30: aload_11: invokeinterface #6,  1            // InterfaceMethod javax/servlet/http/HttpServletRequest.getRequestURI:()Ljava/lang/String;6: astore_37: aload_18: invokeinterface #7,  1            // InterfaceMethod javax/servlet/http/HttpServletRequest.getParameterMap:()Ljava/util/Map;13: astore        415: aload_116: invokeinterface #8,  1            // InterfaceMethod javax/servlet/http/HttpServletRequest.startAsync:()Ljavax/servlet/AsyncContext;21: astore        523: aload         525: invokeinterface #9,  1            // InterfaceMethod javax/servlet/AsyncContext.getRequest:()Ljavax/servlet/ServletRequest;30: ldc           #2                  // String uri32: aload_333: invokeinterface #11,  3           // InterfaceMethod javax/servlet/ServletRequest.setAttribute:(Ljava/lang/String;Ljava/lang/Object;)V38: aload         540: invokeinterface #9,  1            // InterfaceMethod javax/servlet/AsyncContext.getRequest:()Ljavax/servlet/ServletRequest;45: ldc           #4                  // String params47: aload         449: invokeinterface #11,  3           // InterfaceMethod javax/servlet/ServletRequest.setAttribute:(Ljava/lang/String;Ljava/lang/Object;)V54: aload         556: ldc2_w        #12                 // long 2000l59: invokeinterface #14,  3           // InterfaceMethod javax/servlet/AsyncContext.setTimeout:(J)V64: aload_065: getfield      #15                 // Field asyncListener:Ljavax/servlet/AsyncListener;68: invokestatic  #16                 // Method java/util/Objects.nonNull:(Ljava/lang/Object;)Z71: ifeq          8574: aload         576: aload_077: getfield      #15                 // Field asyncListener:Ljavax/servlet/AsyncListener;80: invokeinterface #17,  2           // InterfaceMethod javax/servlet/AsyncContext.addListener:(Ljavax/servlet/AsyncListener;)V85: aload_086: getfield      #18                 // Field executor:Ljava/util/concurrent/ThreadPoolExecutor;89: new           #19                 // class com/common/instance/demo/core/serviceLevel/OneLevelAsyncContext$192: dup93: aload_094: aload_295: invokespecial #20                 // Method com/common/instance/demo/core/serviceLevel/OneLevelAsyncContext$1."<init>":(Lcom/common/instance/demo/core/serviceLevel/OneLevelAsyncContext;Ljava/util/concurrent/Callable;)V98: invokevirtual #21                 // Method java/util/concurrent/ThreadPoolExecutor.submit:(Ljava/util/concurrent/Callable;)Ljava/util/concurrent/Future;101: astore        6103: aload         5105: invokeinterface #22,  1           // InterfaceMethod javax/servlet/AsyncContext.complete:()V110: aload         6112: invokeinterface #23,  1           // InterfaceMethod java/util/concurrent/Future.get:()Ljava/lang/Object;117: areturnLineNumberTable:line 34: 0line 36: 7line 39: 15line 40: 23line 41: 38line 43: 54line 44: 64line 45: 74line 49: 85line 58: 103line 59: 110LocalVariableTable:Start  Length  Slot  Name   Signature0     118     0  this   Lcom/common/instance/demo/core/serviceLevel/OneLevelAsyncContext;0     118     1 request   Ljavax/servlet/http/HttpServletRequest;0     118     2  task   Ljava/util/concurrent/Callable;7     111     3   uri   Ljava/lang/String;15     103     4 params   Ljava/util/Map;23      95     5 asyncContext   Ljavax/servlet/AsyncContext;103      15     6 future   Ljava/util/concurrent/Future;LocalVariableTypeTable:Start  Length  Slot  Name   Signature0     118     2  task   Ljava/util/concurrent/Callable<Ljava/lang/Object;>;15     103     4 params   Ljava/util/Map<Ljava/lang/String;[Ljava/lang/String;>;103      15     6 future   Ljava/util/concurrent/Future<Ljava/lang/Object;>;StackMapTable: number_of_entries = 1frame_type = 254 /* append */offset_delta = 85locals = [ class java/lang/String, class java/util/Map, class javax/servlet/AsyncContext ]Exceptions:throws java.util.concurrent.ExecutionException, java.lang.InterruptedExceptionMethodParameters:Name                           Flagsrequest                        finaltask                           finalSignature: #89                          // (Ljavax/servlet/http/HttpServletRequest;Ljava/util/concurrent/Callable<Ljava/lang/Object;>;)Ljava/lang/Object;public void afterPropertiesSet() throws java.lang.Exception;descriptor: ()Vflags: ACC_PUBLICCode:stack=9, locals=3, args_size=10: ldc           #24                 // String 1002: invokestatic  #25                 // Method java/lang/Integer.parseInt:(Ljava/lang/String;)I5: istore_16: ldc           #26                 // String 2008: invokestatic  #25                 // Method java/lang/Integer.parseInt:(Ljava/lang/String;)I11: istore_212: aload_013: new           #27                 // class java/util/concurrent/LinkedBlockingDeque16: dup17: invokespecial #28                 // Method java/util/concurrent/LinkedBlockingDeque."<init>":()V20: putfield      #29                 // Field queue:Ljava/util/concurrent/LinkedBlockingDeque;23: aload_024: new           #30                 // class java/util/concurrent/ThreadPoolExecutor27: dup28: iload_129: iload_230: ldc2_w        #31                 // long 100l33: getstatic     #33                 // Field java/util/concurrent/TimeUnit.MILLISECONDS:Ljava/util/concurrent/TimeUnit;36: aload_037: getfield      #29                 // Field queue:Ljava/util/concurrent/LinkedBlockingDeque;40: invokespecial #34                 // Method java/util/concurrent/ThreadPoolExecutor."<init>":(IIJLjava/util/concurrent/TimeUnit;Ljava/util/concurrent/BlockingQueue;)V43: putfield      #18                 // Field executor:Ljava/util/concurrent/ThreadPoolExecutor;46: aload_047: getfield      #18                 // Field executor:Ljava/util/concurrent/ThreadPoolExecutor;50: iconst_151: invokevirtual #35                 // Method java/util/concurrent/ThreadPoolExecutor.allowCoreThreadTimeOut:(Z)V54: aload_055: getfield      #18                 // Field executor:Ljava/util/concurrent/ThreadPoolExecutor;58: new           #36                 // class com/common/instance/demo/core/serviceLevel/OneLevelAsyncContext$261: dup62: aload_063: invokespecial #37                 // Method com/common/instance/demo/core/serviceLevel/OneLevelAsyncContext$2."<init>":(Lcom/common/instance/demo/core/serviceLevel/OneLevelAsyncContext;)V66: invokevirtual #38                 // Method java/util/concurrent/ThreadPoolExecutor.setRejectedExecutionHandler:(Ljava/util/concurrent/RejectedExecutionHandler;)V69: aload_070: getfield      #15                 // Field asyncListener:Ljavax/servlet/AsyncListener;73: invokestatic  #39                 // Method java/util/Objects.isNull:(Ljava/lang/Object;)Z76: ifeq          9179: aload_080: new           #40                 // class com/common/instance/demo/core/serviceLevel/OneLevelAsyncContext$383: dup84: aload_085: invokespecial #41                 // Method com/common/instance/demo/core/serviceLevel/OneLevelAsyncContext$3."<init>":(Lcom/common/instance/demo/core/serviceLevel/OneLevelAsyncContext;)V88: putfield      #15                 // Field asyncListener:Ljavax/servlet/AsyncListener;91: returnLineNumberTable:line 68: 0line 70: 6line 72: 12line 74: 23line 76: 46line 78: 54line 105: 69line 106: 79line 155: 91LocalVariableTable:Start  Length  Slot  Name   Signature0      92     0  this   Lcom/common/instance/demo/core/serviceLevel/OneLevelAsyncContext;6      86     1 corePoolSize   I12      80     2 maxNumPoolSize   IStackMapTable: number_of_entries = 1frame_type = 253 /* append */offset_delta = 91locals = [ int, int ]Exceptions:throws java.lang.Exception
}
SourceFile: "OneLevelAsyncContext.java"
RuntimeVisibleAnnotations:0: #98()
InnerClasses:#40; //class com/common/instance/demo/core/serviceLevel/OneLevelAsyncContext$3#36; //class com/common/instance/demo/core/serviceLevel/OneLevelAsyncContext$2#19; //class com/common/instance/demo/core/serviceLevel/OneLevelAsyncContext$1

四、字节码指令

        Java各种语法、关键字、常量变量、符号运算的语义最终都会由多个字节码指令组合来表达。Java虚拟机字节码指令组成如下所示:操作码(Opcode)、操作数(Operand)。

       Java虚拟机面向操作数栈而不是面向寄存器的架构,其总数不超过256条(单字节),指令分类如下表所示。 

指令类型

指令作用

指令

加载和存储

局部表加载到操作数栈

1.iload、iload_<n>、aload、aload_<n>、......;

2._<n>:其中n表示局部变量表的slot索引位置

操作数栈存储到局部表

1.istore、istore_<n>、astore、astore_<n>、......;

2._<n>:其中n表示局部变量表的slot索引位置。

常量加载到操作数栈

1.iconst_<i>、aconst_null、bipush、sipush、ldc、......;

2.iconst_<i>表示:int型的常量<i>加载到操作数栈。

扩充局部变量表的访问索引

wide

运算指令

加法指令

iadd、ladd、fadd、dadd

减法指令

isub、lsub、fsub、dsub

局部变量自增指令

iinc

比较指令

dcmpg、dcmpl、fcmpg、fcmpl、cmp

......

imul、idev、irem、ineg、ishl、ior、iadd、ixor、......

对象创建和访问

类实例创建

new

数组创建

newarray、anewarray、multianewarray

访问实例字段或类字段

getfield、putfield、getstatic、putstatic

数组元素加载到操作数栈

iaload、aaload、......

操作数栈存储到数组元素

iastore、aastore、......

获取数组长度

arraylength

检查类实例类型

instanceof、checkcast

操作数栈管理

栈顶一个或两个元素出栈

pop、pop2

栈顶一个或两个元素复制或双份复制重新压入栈顶

dup、dup2、dup_x1、dup2_x1、dup_x2、dup2_x2

最顶端两个元素互换

swap

控制转移

条件分支

ifeq、iflt、ifnull、ificmplt、ifacmpeq、......

复合条件分支

tableswitch、lookupswitch

无条件分支

goto、goto_w、......

方法调用和返回

调用对象实例方法

invokevirtual(运行时实际类型进行动态分派 _ 重写

调用接口方法

invokeinterface(运行时实现该接口的对象,找到合适则调用)

调用实例初始化、私有、父类方法

invokespecial(实例初始化、私有、父类方法)

调用类静态方法

invokestatic(static方法)

动态调用用户设定的方法

invokedunamic(运行时动态解析调用点限定符所引用的方法)

方法返回

1.return(void、实例初始化、类或接口初始化方法);

2.ireturn、lreturn、freturn、dreturn、areturn

 (byte、short、char、boolean、int型返回使用ireturn)

异常处理

显示抛出异常

athrow(throw语句 + 检测到异常状况自动抛出)

同步处理

synchronized加锁

(都是使用管程Monitor

1.方法的隐式加锁,即:方法访问标志ACC_SYNCHRONIZED;

2.语句块的显示加锁,即:monitorenter + monitorexit

类型转换

宽化类型转换(安全转换)

JVM直接支持:i转l/f/d、l转f/d、f转d

窄化类型转换(强制转换)

i2b、i2c、i2s、l2i、f2l、d2f、......

注意:

   a.i代表int、l代表long、s代表short、b代表byte、c代表char、f代表float、d代表double、a代表reference型;

   b.JVM不直接支持byte、short、char、boolean类型的算术运算,转换为int型运算

   c.算术指令对操作数栈顶的两个元素运算,运算后先移除这两个元素,后计算结果存入栈顶

   d.invokevirtual、invokeinterface、invokespecial、invokestatic调用都固化在JVM内部;而invokedunamic是由用户所设定的引导方法决定的

   e.方法无论正常结果还是异常结束,则每条monitorenter都必须对应monitorexit;

   f.算术运算时,使用NaN(Not a Number)运算,其结果都是NaN。

五、参考资料

jdk/jdk12: log

Java 进阶之字节码剖析_aload_0_C陈三岁的博客-CSDN博客

Class文件解析_class 详解_Aur_ora的博客-CSDN博客

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/52530.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

C语言阶段性测试题

【前言】&#xff1a;本部分是C语言初阶学完阶段性测试题&#xff0c;最后一道编程题有一定的难度&#xff0c;需要多去揣摩&#xff0c;代码敲多了&#xff0c;自然就感觉不难了&#xff0c;加油&#xff0c;铁汁们&#xff01;&#xff01;&#xff01; 一、选择题 1.下面程…

微信小程序中的全局数据共享(状态管理)使用介绍

开发工具&#xff1a;微信开发者工具Stable 1.06 一、状态管理简介 微信小程序全局状态是指可以在不同页面之间共享的数据或状态。 它可以存储用户的登录状态、个人信息、全局配置信息等。 二、安装MobX 1、安装NPM 在资源管理器的空白地方点右键&#xff0c;选择“在外部…

【深度学习_TensorFlow】激活函数

写在前面 上篇文章我们了解到感知机使用的阶跃函数和符号函数&#xff0c;它们都是非连续&#xff0c;导数为0的函数&#xff1a; 建议回顾上篇文章&#xff0c;本篇文章将介绍神经网络中的常见激活函数&#xff0c;这些函数都是平滑可导的&#xff0c;适合于梯度下降算法。 写…

【知识产权】专利的弊端

接上篇【知识产权】著作权的作用_qilei2010的博客-CSDN博客。 ​ 1 专利的分类 首先,专利分为:发明专利、实用新型专利、外观设计专利。这里要说明的是专利的不同种类在不同的国家都是有不同规定的,并不是所有国家和地区都是分成这三类。 >国家法律法规数据库 >中华…

redis入门2-命令

Redis的基本数据类型 redis的基本数据类型&#xff08;value&#xff09;: string,普通字符串 hash&#xff08;哈希&#xff09;,适合存储对象 list(列表),按照插入顺序排序&#xff0c;可以由重复的元素 set(无序集合)&#xff0c;没有重复的元素 sorted set(有序集合)&…

Spring集成Web

目录 1、简介 2、监听器 3、Spring提供的listener 3.1、xml 3.2、配置类 3.3、WebApplicationContextUtils 3.4、说明 4、自己复现的listener 4.1、ContextLoaderListener 4.2、WebApplicationContextUtils 4.3、Web调用 ⭐作者介绍&#xff1a;大二本科网络工程专业…

JVM相关知识

JVM主要有堆、方法区、虚拟机栈、本地方法栈、程序计数器组成 线程私有区域&#xff1a; 程序计数器&#xff1a;字节码执行的都有一个编号&#xff0c;就是程序计数器&#xff0c;解释器按这个计数器执行字码&#xff0c;将字节码转换为机器码给cpu运行。其二就是多线程中&a…

【C++】开源:ncurses终端TUI文本界面库

&#x1f60f;★,:.☆(&#xffe3;▽&#xffe3;)/$:.★ &#x1f60f; 这篇文章主要介绍ncurses终端文本界面库。 无专精则不能成&#xff0c;无涉猎则不能通。——梁启超 欢迎来到我的博客&#xff0c;一起学习&#xff0c;共同进步。 喜欢的朋友可以关注一下&#xff0c;下…

【计算机视觉】干货分享:Segmentation model PyTorch(快速搭建图像分割网络)

一、前言 如何快速搭建图像分割网络&#xff1f; 要手写把backbone &#xff0c;手写decoder 吗&#xff1f; 介绍一个分割神器&#xff0c;分分钟搭建一个分割网络。 仓库的地址&#xff1a; https://github.com/qubvel/segmentation_models.pytorch该库的主要特点是&#…

运输层---概述

目录 运输层主要内容一.概述和传输层服务1.1 概述1.2 传输服务和协议1.3 传输层 vs. 网络层1.4 Internet传输层协议 二. 多路复用与多路分解&#xff08;解复用&#xff09;2.1 概述2.2 无连接与面向连接的多路分解&#xff08;解复用&#xff09;2.3面向连接的多路复用*2.4 We…

STM32刷Micropython固件参考指南

STM32刷Micropython固件指南 其实刷固件和普通的程序下载烧录无多大的差异&#xff0c;主要是其他因数的影响导致刷固件或刷完固件无法运行的情况和相关问题。 &#x1f4d1;刷固件教程 固件下载。目前所支持的stm32型号有这些&#xff1a; stm32f0, stm32f4, stm32f7, stm32g…

基于C#的窗体阴影效果方案 - 开源研究系列文章

最近在研究C#的Winform窗体的效果&#xff0c;上次介绍了窗体动画效果的博文( 基于C#的无边框窗体动画效果的完美解决方案 - 开源研究系列文章 )&#xff0c;这次将窗体阴影效果的方案进行一个介绍。 找了一下度娘&#xff0c;具体窗体阴影效果就两种方法&#xff1a;直接绘制和…