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

news2024/9/29 15:25:22

目录

一、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 {
        // 获取请求URI
        final 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>() {
            @Override
            public Object call() throws Exception {
                // 业务处理
                Object result = task.call();
                return result;
            }
        });
        // 完成异步上下文,否则报超时等异常
        asyncContext.complete();
        return future.get();
    }



    // 完成初始化配置
    @Override
    public 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() {
            @Override
            public 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() {
                @Override
                public void onComplete(AsyncEvent asyncEvent) throws IOException {

                }

                @Override
                public 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();
                    }
                }

                @Override
                public 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();
                    }
                }

                @Override
                public 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.class
  Last modified 2023-7-22; size 4120 bytes
  MD5 checksum ab1d73e3259040031896505e9ed1e1bb
  Compiled from "OneLevelAsyncContext.java"
public class com.common.instance.demo.core.serviceLevel.OneLevelAsyncContext implements org.springframework.beans.factory.InitializingBean
  minor version: 0
  major version: 52
  flags: 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: ()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: ldc           #2                  // String uri
         7: putfield      #3                  // Field URI:Ljava/lang/String;
        10: aload_0
        11: ldc           #4                  // String params
        13: putfield      #5                  // Field PARAMS:Ljava/lang/String;
        16: return
      LineNumberTable:
        line 23: 0
        line 25: 4
        line 26: 10
      LocalVariableTable:
        Start  Length  Slot  Name   Signature
            0      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_PUBLIC
    Code:
      stack=5, locals=7, args_size=3
         0: aload_1
         1: invokeinterface #6,  1            // InterfaceMethod javax/servlet/http/HttpServletRequest.getRequestURI:()Ljava/lang/String;
         6: astore_3
         7: aload_1
         8: invokeinterface #7,  1            // InterfaceMethod javax/servlet/http/HttpServletRequest.getParameterMap:()Ljava/util/Map;
        13: astore        4
        15: aload_1
        16: invokeinterface #8,  1            // InterfaceMethod javax/servlet/http/HttpServletRequest.startAsync:()Ljavax/servlet/AsyncContext;
        21: astore        5
        23: aload         5
        25: invokeinterface #9,  1            // InterfaceMethod javax/servlet/AsyncContext.getRequest:()Ljavax/servlet/ServletRequest;
        30: ldc           #2                  // String uri
        32: aload_3
        33: invokeinterface #11,  3           // InterfaceMethod javax/servlet/ServletRequest.setAttribute:(Ljava/lang/String;Ljava/lang/Object;)V
        38: aload         5
        40: invokeinterface #9,  1            // InterfaceMethod javax/servlet/AsyncContext.getRequest:()Ljavax/servlet/ServletRequest;
        45: ldc           #4                  // String params
        47: aload         4
        49: invokeinterface #11,  3           // InterfaceMethod javax/servlet/ServletRequest.setAttribute:(Ljava/lang/String;Ljava/lang/Object;)V
        54: aload         5
        56: ldc2_w        #12                 // long 2000l
        59: invokeinterface #14,  3           // InterfaceMethod javax/servlet/AsyncContext.setTimeout:(J)V
        64: aload_0
        65: getfield      #15                 // Field asyncListener:Ljavax/servlet/AsyncListener;
        68: invokestatic  #16                 // Method java/util/Objects.nonNull:(Ljava/lang/Object;)Z
        71: ifeq          85
        74: aload         5
        76: aload_0
        77: getfield      #15                 // Field asyncListener:Ljavax/servlet/AsyncListener;
        80: invokeinterface #17,  2           // InterfaceMethod javax/servlet/AsyncContext.addListener:(Ljavax/servlet/AsyncListener;)V
        85: aload_0
        86: getfield      #18                 // Field executor:Ljava/util/concurrent/ThreadPoolExecutor;
        89: new           #19                 // class com/common/instance/demo/core/serviceLevel/OneLevelAsyncContext$1
        92: dup
        93: aload_0
        94: aload_2
        95: invokespecial #20                 // Method com/common/instance/demo/core/serviceLevel/OneLevelAsyncContext$1."<init>":(Lcom/common/instance/demo/core/serviceLevel/OneLevelAsyncContext;Ljava/util/concurrent/Callable;)V
        98: invokevirtual #21                 // Method java/util/concurrent/ThreadPoolExecutor.submit:(Ljava/util/concurrent/Callable;)Ljava/util/concurrent/Future;
       101: astore        6
       103: aload         5
       105: invokeinterface #22,  1           // InterfaceMethod javax/servlet/AsyncContext.complete:()V
       110: aload         6
       112: invokeinterface #23,  1           // InterfaceMethod java/util/concurrent/Future.get:()Ljava/lang/Object;
       117: areturn
      LineNumberTable:
        line 34: 0
        line 36: 7
        line 39: 15
        line 40: 23
        line 41: 38
        line 43: 54
        line 44: 64
        line 45: 74
        line 49: 85
        line 58: 103
        line 59: 110
      LocalVariableTable:
        Start  Length  Slot  Name   Signature
            0     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   Signature
            0     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 = 1
        frame_type = 254 /* append */
          offset_delta = 85
          locals = [ class java/lang/String, class java/util/Map, class javax/servlet/AsyncContext ]
    Exceptions:
      throws java.util.concurrent.ExecutionException, java.lang.InterruptedException
    MethodParameters:
      Name                           Flags
      request                        final
      task                           final
    Signature: #89                          // (Ljavax/servlet/http/HttpServletRequest;Ljava/util/concurrent/Callable<Ljava/lang/Object;>;)Ljava/lang/Object;

  public void afterPropertiesSet() throws java.lang.Exception;
    descriptor: ()V
    flags: ACC_PUBLIC
    Code:
      stack=9, locals=3, args_size=1
         0: ldc           #24                 // String 100
         2: invokestatic  #25                 // Method java/lang/Integer.parseInt:(Ljava/lang/String;)I
         5: istore_1
         6: ldc           #26                 // String 200
         8: invokestatic  #25                 // Method java/lang/Integer.parseInt:(Ljava/lang/String;)I
        11: istore_2
        12: aload_0
        13: new           #27                 // class java/util/concurrent/LinkedBlockingDeque
        16: dup
        17: invokespecial #28                 // Method java/util/concurrent/LinkedBlockingDeque."<init>":()V
        20: putfield      #29                 // Field queue:Ljava/util/concurrent/LinkedBlockingDeque;
        23: aload_0
        24: new           #30                 // class java/util/concurrent/ThreadPoolExecutor
        27: dup
        28: iload_1
        29: iload_2
        30: ldc2_w        #31                 // long 100l
        33: getstatic     #33                 // Field java/util/concurrent/TimeUnit.MILLISECONDS:Ljava/util/concurrent/TimeUnit;
        36: aload_0
        37: 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;)V
        43: putfield      #18                 // Field executor:Ljava/util/concurrent/ThreadPoolExecutor;
        46: aload_0
        47: getfield      #18                 // Field executor:Ljava/util/concurrent/ThreadPoolExecutor;
        50: iconst_1
        51: invokevirtual #35                 // Method java/util/concurrent/ThreadPoolExecutor.allowCoreThreadTimeOut:(Z)V
        54: aload_0
        55: getfield      #18                 // Field executor:Ljava/util/concurrent/ThreadPoolExecutor;
        58: new           #36                 // class com/common/instance/demo/core/serviceLevel/OneLevelAsyncContext$2
        61: dup
        62: aload_0
        63: invokespecial #37                 // Method com/common/instance/demo/core/serviceLevel/OneLevelAsyncContext$2."<init>":(Lcom/common/instance/demo/core/serviceLevel/OneLevelAsyncContext;)V
        66: invokevirtual #38                 // Method java/util/concurrent/ThreadPoolExecutor.setRejectedExecutionHandler:(Ljava/util/concurrent/RejectedExecutionHandler;)V
        69: aload_0
        70: getfield      #15                 // Field asyncListener:Ljavax/servlet/AsyncListener;
        73: invokestatic  #39                 // Method java/util/Objects.isNull:(Ljava/lang/Object;)Z
        76: ifeq          91
        79: aload_0
        80: new           #40                 // class com/common/instance/demo/core/serviceLevel/OneLevelAsyncContext$3
        83: dup
        84: aload_0
        85: invokespecial #41                 // Method com/common/instance/demo/core/serviceLevel/OneLevelAsyncContext$3."<init>":(Lcom/common/instance/demo/core/serviceLevel/OneLevelAsyncContext;)V
        88: putfield      #15                 // Field asyncListener:Ljavax/servlet/AsyncListener;
        91: return
      LineNumberTable:
        line 68: 0
        line 70: 6
        line 72: 12
        line 74: 23
        line 76: 46
        line 78: 54
        line 105: 69
        line 106: 79
        line 155: 91
      LocalVariableTable:
        Start  Length  Slot  Name   Signature
            0      92     0  this   Lcom/common/instance/demo/core/serviceLevel/OneLevelAsyncContext;
            6      86     1 corePoolSize   I
           12      80     2 maxNumPoolSize   I
      StackMapTable: number_of_entries = 1
        frame_type = 253 /* append */
          offset_delta = 91
          locals = [ 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.coloradmin.cn/o/837463.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

wonderful-sql 作业

Sql 作业 作业1&#xff1a; 答&#xff1a; create table Employee (Id integer not null, Name varchar(32) , Salary integer, departmentId integer, primary key (Id) );create table Department( Id integer primary key, Name varchar(30) not null );insert into emp…

《向量数据库指南》——使用 AI原生云向量数据库Milvus Cloud的好处

目录 3. 使用 Milvus Cloud的好处 a. 高效存储和检索 b. 高度灵活、可扩展 c. 高性能、高可用 d. 易用性 e. 可靠性 3. 使用 Milvus Cloud的好处 Milvus Cloud生态系统提供了有效的数据库监控、数据迁移和数据量估算工具。如果不想要花时间和精力维护 Milvus,也可以选择…

k8s存储卷

目录 一、为什么要存储卷&#xff1f;二、emptyDir存储卷三、hostPath存储卷四、 nfs共享存储卷五、PVC 和 PV5.1 PV和PVC之间的相互作用遵循的生命周期5.2 PV 的状态5.3 一个PV从创建到销毁的具体流程 六、静态创建pv和pvc资源由pod运用过程6.1 在NFS主机上创建共享目录&#…

记录一次Linux环境下遇到“段错误核心已转储”然后利用core文件解决问题的过程

参考Linux 下Coredump分析与配置 在做项目的时候&#xff0c;很容易遇到“段错误&#xff08;核心已转储&#xff09;”的问题。如果是语法错误还可以很快排查出来问题&#xff0c;但是碰到coredump就没办法直接找到问题&#xff0c;可以通过设置core文件来查找问题&#xff0…

SSM(Vue3+ElementPlus+Axios+SSM前后端分离)--搭建Vue 前端工程[一]

文章目录 SSM--搭建Vue 前端工程--项目基础界面实现功能01-搭建Vue 前端工程需求分析/图解代码实现搭建Vue 前端工程下载node.js LTS 并安装: node.js 的npm创建Vue 项目使用idea 打开ssm_vue 项目, 并配置项目启动 Vue3 项目目录结构梳理Vue3 项目结构介绍 配置Vue 服务端口El…

本地 shell无法连接centos 7 ?

1、首先检查是否安装ssh服务&#xff1b; yum list installed | grep openssh-server# 没有安装尝试安装下 yum install openssh-server 2、检查ssh服务是否开启 systemctl status sshd.service# 未开启&#xff0c;开启下 systemctl start sshd.service # 将sshd 服务添…

router 跳转打开新窗口

let url router.resolve({name: screen, })?.hrefwindow.open(url, _black)注意&#xff1a;新窗口无法全屏 参考链接&#xff1a;https://stackoverflow.com/questions/29281986/run-a-website-in-fullscreen-mode/30970886#30970886

路由表、转发表

文章目录 1.路由表1.1.查询路由表的开销 2.转发表3.两个表的关系3.1.联系3.2.区别 4.误区5.区分二表的好处之实例6.Linux中通过NAT原理配置转发表7.优势8、转发表与MAC表9、IP VS MAC 1.路由表 路由信息最终要存储在用于路由器的主机或者专业路由器上&#xff0c;存放这些信息…

【单片机】51单片机串口的收发实验,串口程序

这段代码是使用C语言编写的用于8051单片机的串口通信程序。它实现了以下功能&#xff1a; 引入必要的头文件&#xff0c;包括reg52.h、intrins.h、string.h、stdio.h和stdlib.h。 定义了常量FSOC和BAUD&#xff0c;分别表示系统时钟频率和波特率。 定义了一个发送数据的函数…

基于web特产店销售管理系统的设计与实现(论文+源码)_kaic

摘要 农业是我国国民经济的重要组成部分&#xff0c;随着信息化的普及&#xff0c;4G网络、光纤以及5G网络也日益完善&#xff0c;农业信息化的发展成为了必然。同时&#xff0c;由于本年疫情原因&#xff0c;导致农作物积压销售&#xff0c;甚至腐烂造成不必要的浪费&#xff…

k8s ingress获取客户端客户端真实IP

背景 在Kubernetes中&#xff0c;获取客户端真实IP地址是一个常见需求。这是因为在负载均衡架构中&#xff0c;原始请求的源IP地址会被替换成负载均衡器的IP地址。 获取客户端真实IP的需求背景包括以下几点&#xff1a; 安全性&#xff1a;基于客户端IP进行访问控制和认证授…

Java阶段五Day20

Java阶段五Day20 文章目录 Java阶段五Day20项目推进完成订单OrderServerService && MessageTransSenderRepositoryMessageTransRepoImplLocalTransactionLisetner 结算订单业务流程图远程调用 画时序图 项目推进 完成订单 通过分布式消息事务解决本地事务和发消息的一…

精选5个AI绘画工具,灵感与创意迸发!

伴随着AI技术的发展&#xff0c;AI绘画工具也走进了人们的视线&#xff0c;今天本文将为大家推荐5个最近火爆的AI绘画神器&#xff0c;一起来看看吧&#xff01; 1、即时灵感 即时灵感是一个国产的AI绘画神器&#xff0c;非常受国内设计师的欢迎。它支持设计师使用中文描述词…

面向视频会议场景的 H.266/VVC 码率控制算法研究

文章目录 面向视频会议场景的 H.266/VVC 码率控制算法研究个人总结摘要为什么要码率控制码率控制的关键会议类视频码率控制研究背景视频会议系统研究现状目前基于 R-λ模型的码率控制算法的问题文章主要两大优化算法优化算法1&#xff1a;基于视频内容相关特征值的码率控制算法…

网安周报|CISA对梭鱼ESG攻击中使用的潜艇后门发出警告

1、CISA对梭鱼ESG攻击中使用的潜艇后门发出警告 美国网络安全与基础设施安全局&#xff08;CISA&#xff09;发布了一条针对恶意软件变体的警报&#xff0c;该变体被追踪为SUBMARINE Backdoor&#xff0c;用于利用该漏洞进行攻击 CVE-223-2868在Barracuda电子邮件安全网关&…

斯坦福大学提出在类别层级对多零件多关节三维拼装新方法

来源&#xff1a;投稿 作者&#xff1a;橡皮 编辑&#xff1a;学姐 paper&#xff1a;https://arxiv.org/pdf/2303.06163.pdf 背景&#xff1a; 形状装配通过排列一组简单或基本的零件几何图形来组成复杂的形状几何图形。许多重要的任务和应用都依赖于形状装配算法。 计算机…

redis初级

Redis 课程内容 Redis入门Redis数据类型Redis常用命令在Java中操作RedisRedis持久化机制 1. Redis入门 1.1 Redis简介 Redis是一个基于内存的key-value结构数据库。Redis 是互联网技术领域使用最为广泛的存储中间件。 **官网&#xff1a;**https://redis.io **中文网&…

推荐前端开发者提升效率的工具

是否掌握新的技术很大程度决定着你是否被淘汰。 虽然应用程序试图将网站替代&#xff0c;但前端 Web 开发业务仍在快速变化和增长&#xff0c;前端开发人员的功能并没有消失。以下介绍一款前端开发者提升效率的工具。 目录 一、低代码工具前景 二、如何理解低代码工具 三、前端…

直播预告|还在说做不出、改不好地图贴图?一次直播包教包会!

在EasyV中&#xff0c;地图组件通常会作为可视化大屏中的「主视觉」部分&#xff0c;用户通过地图组件的使用&#xff0c;可以极大程度上提高搭建的效率以及视觉效果。正因如此&#xff0c;我们的素材广场中大多模板也将「地图」作为核心部分&#xff0c;以此来方便用户快速套用…

203. 移除链表元素

203. 移除链表元素 题目方法1递归方法2迭代 题目 给你一个链表的头节点 head 和一个整数 val &#xff0c;请你删除链表中所有满足 Node.val val 的节点&#xff0c;并返回 新的头节点 。 方法1递归 class Solution { public:ListNode* removeElements(ListNode* head, in…