微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

1001.1.jvm基础1-class文件的加载

1. jvm是干什么的?

初步理解:

​ jvm是运行 java等语言源码编译后的class文件一个应用。

2. class文件是什么?

class文件时字节码文件,宽泛的说也就是由程序员写的代码翻译而成的机器识别的二进制码文件

class文件包含了哪些信息:

基本分析:

编号源码及编译相关信息推class对应的字节数基本逻辑
1class文件的标识魔数cafe babe4jvm需要一眼就知道这是不是我能处理的文件
2编译器版本大小两个版本4jvm需要知道编译他的是哪个版本,不同版本有差异
3类信息类信息表--
4方法信息方法信息表--
5属性信息属性信息表--

实际情况:

编号类型描述备注
1u4magic魔数:0xCAFEBABE
2u2minor_version小版本号
3u2major_version主版本号
4u2constant_pool_count常量池大小,从1开始
5cp_infoconstant_pool[constant_pool_count - 1]常量池信息
6u2access_flags访问标志
7u2this_class类索引
8u2super_class父类索引
9u2interfaces_count接口个数
10u2interfaces[interfaces_count]接口类索引信息
11u2fields_count字段数
12field_infofields[fields_count]字段表信息
13u2methods_count方法
14method_infomethods[methods_count]方法表信息
15u2attributes_count属性个数
16attribute_infoattributes[attributes_count]属性表信息

java空类示例:

package com.jgp.practice.bytecode;

import java.io.Serializable;

/**
 * 用jclasslib插件查看class码内容
 */
public class ByteCode01 implements Serializable {

}

对应字节码文件:

ca fe ba be 00 00 00 34 00 12 0a 00 03 00 0e 07   
00 0f 07 00 10 07 00 11 01 00 06 3c 69 6e 69 74  
3e 01 00 03 28 29 56 01 00 04 43 6f 64 65 01 00 
0f 4c 69 6e 65 4e 75 6d 62 65 72 54 61 62 6c 65
01 00 12 4c 6f 63 61 6c 56 61 72 69 61 62 6c 65   
54 61 62 6c 65 01 00 04 74 68 69 73 01 00 26 4c
63 6f 6d 2f 6a 67 70 2f 70 72 61 63 74 69 63 65 
2f 62 79 74 65 63 6f 64 65 2f 42 79 74 65 43 6f 
64 65 30 31 3b 01 00 0a 53 6f 75 72 63 65 46 69 
6c 65 01 00 0f 42 79 74 65 43 6f 64 65 30 31 2e 
6a 61 76 61 0c 00 05 00 06 01 00 24 63 6f 6d 2f 
6a 67 70 2f 70 72 61 63 74 69 63 65 2f 62 79 74 
65 63 6f 64 65 2f 42 79 74 65 43 6f 64 65 30 31 
01 00 10 6a 61 76 61 2f 6c 61 6e 67 2f 4f 62 6a 
65 63 74 01 00 14 6a 61 76 61 2f 69 6f 2f 53 65 
72 69 61 6c 69 7a 61 62 6c 65 00 21 00 02 00 03 
00 01 00 04 00 00 00 01 00 01 00 05 00 06 00 01 
00 07 00 00 00 2f 00 01 00 01 00 00 00 05 2a b7 
00 01 b1 00 00 00 02 00 08 00 00 00 06 00 01 00 
00 00 08 00 09 00 00 00 0c 00 01 00 00 00 05 00  
0a 00 0b 00 00 00 01 00 0c 00 00 00 02 00 0d 

在命令行使用“javap -v class文件名”或者再idea中使用jclasslib插件查看字节码文件对应的汇编

3. class文件如何被加载到jvm虚拟机

jvm想使用class文件内容必须将class加载到内存中,并且保持对应内存的位置。

实际上用于保持class加载到的内存的是class对象,其存在于Metaspace(元空间)中。

3.1. loading(加载)

加载由类加载器完成

类加载器有哪些:

编号名称备注
1Bootstrap加载lib/rt.jar charset.jar等核心类,c++实现
2Extension加载扩展jar包 jre/lib/ext/*.jar或者由-Djava.ext.dirs指定
3App加载classpath指定内容
4CustomClassLoader自定义ClassLoader

1. 双亲委派机制:

从下向上检查该类是否已经加载未加载则沿parent方向检查是否被加载一旦有被加载的就返回,如果所有加载器都没有进行加载,则自顶向下沿着child方向委托加载,在自己加载范围内则自己加载,不在则委托child加载,如果找到则加载,找不到就报出class not found异常。

为什么要有双亲委派:

主要是为了安全,避免了子加载器覆盖掉父加载器加载的类。

其次是避免加载重复

注意,对于加载器来说:父加载器不是类加载器的加载器,也不是类加载器的父类

源码中父加载器是加载器对象中parent通过getParent获取

2. LazyLoading 五种情况

  1. –new getstatic putstatic invokestatic指令,访问final变量除外

    java.lang.reflect对类进行反射调用

    –初始化子类的时候,父类首先初始化

    –虚拟机启动时,被执行的主类必须初始化

    –动态语言支持java.lang.invoke.MethodHandle解析的结果为REF_getstatic REF_putstatic REF_invokestatic的方法句柄时,该类必须初始化

3. ClassLoader的源码

  1. findInCache -> parent.loadClass -> findClass()

4. 自定义类加载器

  1. extends ClassLoader
  2. overwrite findClass() -> defineClass(byte[] -> Class clazz)
  3. 加密
  4. 第一节课遗留问题:parent是如何指定的,打破双亲委派,学生问题桌面图片@H_617_404@
    1. 用super(parent)指定
    2. 双亲委派的打破
      1. 如何打破:重写loadClass()
      2. 何时打破过?
        1. JDK1.2之前,自定义ClassLoader都必须重写loadClass()
        2. threadcontextClassLoader可以实现基础类调用实现类代码,通过thread.setContextClassLoader指定
        3. 热启动,热部署
          1. osgi tomcat 都有自己的模块指定classloader(可以加载同一类库的不同版本)

5. 混合执行 编译执行 解释执行

  1. 检测热点代码:-XX:CompileThreshold = 10000

3.2. linking(链接

3.2.1. verification(校验)

  1. 验证文件是否符合JVM规定

3.2.2. preparation(赋认值)

  1. 静态成员变量赋认值

3.2.3. resolution(简历内存关联)

  1. 将类、方法属性等符号引用解析为直接引用
    常量池中的各种符号引用解析为指针、偏移量等内存地址的直接引用

3.3. initializing(初始化)

  1. 调用类初始化代码 ,给静态成员变量赋初始值

3.4. 小总结

  1. load - 认值 - 初始值
  2. new - 申请内存 - 认值 - 初始值

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。

相关推荐