你能说出jvm的类加载是什么吗(1)

「这是我参与2022首次更文挑战的第1天,活动详情查看:2022首次更文挑战」。

前言

小伙伴们我回来更文啦,其实是临近过年空出时间了,哈哈。

看了上面的标题,有没有小伙伴觉得类加载和我们其实很遥远,完全不需要关注,赞同的举个爪。

但仔细回想下,其实你时时刻刻都在和它发生交集,比如:基于动态代理的注解(@Transactional),开发必备的热加载工具:jrebal,排查工具:arthas等。这些足以证明它很重要。

这个专栏的文章灵感来源于自己想造个类似于SpringBootDevTool的轮子。如果你想了解类加载,但又对它很陌生,不知道它怎么实现的。别慌,这个Jvm系列会帮你讲明白。

image.png

类加载步骤

整体的类加载分为以下七个步骤

  1. 加载
  2. 验证
  3. 准备
  4. 解析
  5. 初始化
  6. 使用
  7. 卸载

在这七个步骤中,当然主要关注的只有3个。当然由于篇幅原因,本文主要内容是加载(加载都讲不完!)

什么是类加载

  1. 在创建一个类后,JVM编译器会将.java文件编译成.Class字节码文件。
  2. 然后在JVM启动时,会把描述类的数据从.Class文件(非必须)加载到内存,并对数据进行校验、转换解析和初始化。
  3. 最终形成可以被JVM直接使用的Java类型,放在JVM的各块内存区域中。

字节码来源

上文写了Class文件加载到内存,那有没有其他形式呢?往下看!

  1. 从ZIP包中读取。 例子: jar包
  2. 从网络中获取。 参考: UrlClassLoader(接下来的jvm系列会讲)
  3. 运行时计算生成。 动态代理技术:AOP
  4. 由其他文件生成。 例子:Jsp文件
  5. 从数据库中读取。 我也没试过..

类加载器

既然需要加载类,那我们自然需要某种工具。在JVM中,这就是大名鼎鼎的类加载器了。

在我们的代码设计中,有着低耦合和高内聚的设计原则。在类加载器中,为了将职责区分开,并且保证JDK基本代码和项目中的业务代码区分开等各种原因,JVM定义了不同的类加载器:BootstrapClassLoader,ExtensionClassLoaderAppClassLoader。它们各自都有着自己的加载路径和加载时机。

Bootstrap ClassLoader

  1. 加载路径:lib/rt.jar等类
  2. 加载时机:jvm启动时

在启动jvm时添加该命令, -XX:+TraceClassLoading,就能看到加载的类啦。有没有发现下图的类很熟悉

image.png

image.png

Extension ClassLoader

  1. 加载路径:jre/lib/ext, 如果用户自定义Jar包也在该路径,同样会被加载
  2. 加载时机:jvm启动时

App ClassLoader

  1. 加载路径:应用程序当前路径
  2. 加载时机:系统启动时需要加载的类,例如:SpringBoot下Controller。或者项目运行时加载的类

image.png

自定义 ClassLoader

  1. 加载路径:类加载器设置的地方
  2. 加载时机:手动触发

结尾

这篇文章到这里就结束了。本文介绍了什么是类加载,同时粗略的讲了类加载的工具->类加载器。下篇将会着重介绍JVM是如何巧妙使用这些类加载器,也就是双亲委派模型的实现。

喜欢这篇文章的话点个赞哦,咱们下期见!!

猜你喜欢

转载自juejin.im/post/7054893056344096776