探究JVM——从字节码到对象(类加载、ClassLoader、双亲委派机制、方法区类信息、Class对象)

引言

众所周知,Java代码被编译器处理成字节码文件,然后存放在计算机的硬盘之上,但程序运行时CPU是与内存打交道的,这就需要把字节码文件加载到内存中去并生成一个个的实例对象,此篇文章将剖析此过程,弄清楚安眠于硬盘中字节码是如何变成生龙活虎的对象滴。

ClassLoader 类加载器

顾名思意,类加载器的作用就是把Class文件加载到内存,之后生成一个Class对象。class文件可以来自于本地硬盘、jar包、网络流甚至是基于动态代理技术运行时计算生成的,只要符合JVM规范所规定的格式都能被加载。
类加载过程
类加载器可大致分为两类:虚拟机自带类加载器与用户自定义的加载器。

虚拟机自带类加载器

  • Bootstrap ClassLoader
    此加载器为最底层最基础的加载器,使用C/C++语言实现,嵌套在了JVM内部,用于加载Java的核心库(JAVA_HOME/jre/lib/rt.jar、resource.jar 或sun.boot.class.path路径下的内容)与拓展类加载器 Extension ClassLoader 和应用程序类加载器 APPClassLoader,并为他们指定父类加载器,也就是说这个类加载器加载了其他的类加载器,所以它叫启动加载器。另外出于安全考虑,Bootstrap启动类加载器只加载java、javax、sun等开头的类。

  • Extension ClassLoader 与 APPClassLoader
    这个两个加载器由Java语言编写,派生于ClassLoader类。ExtensionClassLoader 负责加载 JVM 扩展类,比如 swing 系列、内置的 js 引擎、xml 解析器 等等,这些库名通常以 javax 开头,它们的 jar 包位于 JAVA_HOME/lib/ext/*.jar 中,有很多 jar 包。
    AppClassLoader 是直接面向我们用户的加载器,它会加载 Classpath 环境变量里定义的路径中的 jar 包和目录。我们自己编写的代码以及使用的第三方 jar 包通常都是由它来加载的。

用户自定义类加载器

大多数情况下JVM所自带的加载器已经足够满足我们的日常需求,但有些情况下比如出于安全性考虑,字节码会被加密,防止被人反编译,此时就需要开发者自定义类加载器解密字节码,并将之加载到内存之中。

双亲委派模式

JVM对于class文件采用的是按需加载的方式,也就是说当程序需要使用到某个类时才会将它的class文件加载到内存,生成class对象,加载时采用了双亲委派模式,此名称看似高大上,实则非常浅显易懂。即每个类加载器都很“懒”,都会先把请求交由上层处理,若上层不能处理,这个类加载器再自己亲自处理。
双亲委派机制
这样做的好处第一避免了类的重复加载,确保class文件只会被加载一次。第二点就是保护了程序的安全,防止核心API被随意篡改。比如下方代码我自己写了一个String类,包名也为java.lang,当我在其他地方使用String类时,仍然会是系统自带的那个String类,而不是我自定义的这个。

package java.lang;
public class String {
    public void say(){
        System.out.println(222);
    }
}

方法区 类信息

class文件加载到内存后会放在JVM的内存模型中有一个叫做方法区的区域,在jdk 1.8之前叫做永久代,之后叫做元空间,该区域保存着每个类(类、接口、枚举)的信息,包括这个类的字段名称、字段类型、修饰符 还有方法名称、方法返回类型、方法参数、方法修饰符……这些信息就是一个类的模板,在调用反射相关的API时,比如getMethods()getFields其底层都会在方法区去寻找相关信息。

Class对象

首先在Java中有个Class类,在一个运行中的Java程序中,每个Class类的实例代表了类与接口。
在这里插入图片描述

当某个.class文件被加载到内存中以后,其并不会变成一个实例对象,而是变成这个类的Class对象,也可以理解为这是一个模板对象,所有的实例对象根据这个模板对象创造而来。

举个栗子:User.class 被加载的内存后变成了Class<? extends User> userClass这个对象,某个对象的Class对象可调用其getClass()来获得。

怎么说呢,这里所谓的加载,说成解析更为贴切,JVM解析.class文件,然后在方法区生成类的基本信息,在堆区生成Class对象。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值