驽马十驾 驽马十驾

驽马十驾,功在不舍

目录
Java类加载器--ClassLoader
/  

Java类加载器--ClassLoader

Java程序启动的时候,不会一次性的将程序需要用到的所有类加载到内存中。JVM会先加载基础类,其他类等到需要使用的时候再进行加载。

什么叫做“需要使用的时候”了?通常而言有如下几种情况:

  • 通过new关键字第一次使用非基础类,比如自己定义的PersonService这类的。
  • 通过Class.forName()的时候。
  • 访问某一个非基础类静态成员的时候。

JDK默认的类加载器

简单而言:JDK默认提供了3个ClassLoader,Bootstrap、Extension、App 3个,前2者通常用于加载JDK自身的jar或者class,app加载的是我们开发过程中引入的包。

Bootstrap Classloader

Bootstrap ClassloaderC++编写的最底层的类加载器,它会加载系统最底层的类,比如rt.jarcharsets.jar这些类。

可以通过如下代码获取加载了哪些

URL[] urls = sun.misc.Launcher.getBootstrapClassPath().getURLs();
for (int i = 0; i < urls.length; i++) {
    System.out.println(urls[i].toExternalForm());
}

Extension Classloader

Extension Classloader被称为扩展类加载器,默认加载C:\Program Files\Java\jre1.8.0_162\lib\ext下的相关类。

App Classloader

App Classloader称为应用类加载器,加载我们应用程序下的 jar包或者 class 文件。该加载器默认情况下,是我们应用程序中引入的包的加载器。

双亲委托机制

简单而言:当需要加载一个class 的时候,默认情况下会通过如下顺序进行查找:自定义的ClassLoader ➡ AppClassloader ➡ ExtensionClassLoader ➡ BootstrapClassloader。

JVM为何要如此设计?从安全来说,保证了核心的class 只会被加载一次,不会被自定义的Classloader篡改。

从如下图可以看出:

类加载器

  • 类加载的时候是 依次向上 委托给父加载器完成的。
  • 如果Bootstrap Classloader 都无法加载,那么自己就自行加载。

JVM结构理解

结合JVM的结构进行理解,Classloader 存储在哪个位置,该图是JDK7下的JVM内存结构。

JVM内存结构

请注意在线程共享中的方法区.

JDK7是存储在 方法区中的 PermGen

JDK8是存储在 堆中的 MetaSpace中。

可以参考:

https://www.cnblogs.com/dennyzhangdd/p/6770188.html

https://www.zhihu.com/question/39990490/answer/84155229

本章只是ClassLoader的入门,其中最关键的是自定义ClassLoader 后续专门通过一个章节讲解。

您有任何建议和意见,请Email联系: hicode_club@163.com

转载请保留出处 HiCode 俱乐部

骐骥一跃,不能十步。驽马十驾,功在不舍。