ClassLoader原理
JVM规范定义了两种类型的类装载器:启动内装载器
(bootstrap)
和用户自定义装载器
(user-defined class loader)
。
一.
ClassLoader
基本概念
1
.
ClassLoader
分类
类装载器是用来把类(class)装载进JVM的。
JVM规范定义了两种类型的类装载器:启动内装载器
(bootstrap)
和用户自定义装载器
(user-defined class loader)
。
JVM在运行时会产生三个ClassLoader:Bootstrap ClassLoader、Extension ClassLoader和AppClassLoader.
Bootstrap是用C++编写的,我们在Java中看不到它,是null,是JVM自带的类装载器,用来装载核心类库,如java.lang.*等。
AppClassLoader
的
Parent
是
ExtClassLoader
,而
ExtClassLoader
的
Parent
为
Bootstrap ClassLoader
。
Java
提供了抽象类
ClassLoader
,所有用户自定义类装载器都实例化自
ClassLoader
的子类。
System Class Loader
是一个特殊的用户自定义类装载器,由
JVM
的实现者提供,在编程者不特别指定装载器的情况下默认装载用户类
。系统类装载器可以通过ClassLoader.getSystemClassLoader() 方法得到。
例1,测试你所使用的JVM的ClassLoader
public class LoaderSample1 {
public static void main(String[] args) {
Class c;
ClassLoader cl;
cl = ClassLoader.getSystemClassLoader();
System.out.println(cl);
while (cl != null ) {
cl = cl.getParent();
System.out.println(cl);
}
try {
c = Class.forName( " java.lang.Object " );
cl = c.getClassLoader();
System.out.println( " java.lang.Object's loader is " + cl);
c = Class.forName( " LoaderSample1 " );
cl = c.getClassLoader();
System.out.println( " LoaderSample1's loader is " + cl);
} catch (Exception e) {
e.printStackTrace();
}
}
}
sun.misc.Launcher$AppClassLoader@1a0c10f
sun.misc.Launcher$ExtClassLoader@e2eec8
null
java.lang.Object's loader is null
LoaderSample1's loader is sun.misc.Launcher$AppClassLoader@1a0c10f
第一行表示,系统类装载器实例化自类sun.misc.Launcher$AppClassLoader
第二行表示,系统类装载器的parent实例化自类sun.misc.Launcher$ExtClassLoader
第三行表示,系统类装载器parent的parent为bootstrap
第四行表示,核心类java.lang.Object是由bootstrap装载的
第五行表示,用户类LoaderSample1是由系统类装载器装载的
二.
parent delegation模型
从1.2版本开始,Java引入了双亲委托模型,从而更好的保证Java平台的安全。在此模型下,当一个装载器被请求装载某个类时,它首先委托自己的
parent
去装载,若
parent
能装载,则返回这个类所对应的
Class
对象,若
parent
不能装载,则由
parent
的请求者去装载
。
图 1 parent delegation模型
如
图1所示,loader2的parent为loader1,loader1的parent为system class
loader。假设loader2被要求装载类MyClass,在parent
delegation模型下,loader2首先请求loader1代为装载,loader1再请求系统类装载器去装载MyClass。若系统装载器能成
功装载,则将MyClass所对应的Class对象的reference返回给loader1,loader1再将reference返回给
loader2,从而成功将类MyClass装载进虚拟机。若系统类装载器不能装载MyClass,loader1会尝试装载MyClass,若
loader1也不能成功装载,loader2会尝试装载。若所有的parent及loader2本身都不能装载,则装载失败。
若有一
个能成功装载,实际装载的类装载器被称为定义类装载器,所有能成功返回Class对象的装载器(包括定义类装载器)被称为初始类装载器。如图1所示,假设
loader1实际装载了MyClass,则loader1为MyClass的定义类装载器,loader2和loader1为MyClass的初始类装
载器。
需要指出的是,Class Loader是对象,它的父子关系和类的父子关系没有任何关系。
那么parent delegation模型为什么更安全了?因为在此模型下用户自定义的类装载器不可能装载应该由父亲装载器装载的可靠类,从而防止不可靠甚至恶意的代码代替由父亲装载器装载的可靠代码。实际上,类装载器的编写者可以自由选择不用把请求委托给
parent
,但正如上所说,会带来安全的问题。
类加载器主要分三种:bootstrap(由C语言编写,固化在jvm上)、ExtClassLoader、AppClassLoader。
而bootstrao主要加载rt.jar,ExtClassLoader主要加载Jdk安装路径/jre/lib/ext下的字节码,
AppClassLoader主要加载ClassPath下的字节码,类加载器的委托加载原理,
首先加载类一直交给父类加载器加载,一直提交到bootstrap,
当父类加载器加载不到时,在一层层的返回给下一级加载器加载
三.命名空间及其作用
每个类装载器有自己的命名空间,命名空间由所有以此装载器为创始类装载器的类组成。不同命名空间的两个类是不可见的,但只要得到类所对应的Class对象的reference,还是可以访问另一命名空间的类。
例
2演示了一个命名空间的类如何使用另一命名空间的类。在例子中,LoaderSample2由系统类装载器装载,LoaderSample3由自定义的装
载器loader负责装载,两个类不在同一命名空间,但LoaderSample2得到了LoaderSample3所对应的Class对象的
reference,所以它可以访问LoaderSampl3中公共的成员(如age)。
例2不同命名空间的类的访问
mport java.net. * ;
import java.lang.reflect. * ;
public class LoaderSample2 {
public static void main(String[] args) {
try {
String path = System.getProperty( " user.dir " );
URL[] us = { new URL( " file:// " + path + " /sub/ " )};
ClassLoader loader = new URLClassLoader(us);
Class c = loader.loadClass( " LoaderSample3 " );
Object o = c.newInstance();
Field f = c.getField( " age " );
int age = f.getInt(o);
System.out.println( " age is " + age);
} catch (Exception e) {
e.printStackTrace();
}
}
}
public class LoaderSample3 {
static {
System.out.println( " LoaderSample3 loaded " );
}
public int age = 30 ;
}
编译:javac LoaderSample2.java; javac sub/LoaderSample3.java
运行:java LoaderSample2
LoaderSample3 loaded
age is 30
从运行结果中可以看出,在类LoaderSample2中可以创建处于另一命名空间的类LoaderSample3中的对象并可以访问其公共成员age。
运行时包(runtime package)
由
同一类装载器定义装载的属于相同包的类组成了运行时包,决定两个类是不是属于同一个运行时包,不仅要看它们的包名是否相同,还要看的定义类装载器是否相
同。只有属于同一运行时包的类才能互相访问包可见的类和成员。这样的限制避免了用户自己的代码冒充核心类库的类访问核心类库包可见成员的情况。假设用户自
己定义了一个类java.lang.Yes,并用用户自定义的类装载器装载,由于java.lang.Yes和核心类库java.lang.*由不同的装
载器装载,它们属于不同的运行时包,所以java.lang.Yes不能访问核心类库java.lang中类的包可见的成员。
加载原则
加载类用的是全盘负责委托机制。所谓全盘负责,即是当一个classloader加载一个Class的时候,这个Class所依赖的和引用的所有 Class也由这个classloader负责载入,除非是显式的使用另外一个classloader载入
总结
命名空间并没有完全禁止属于不同空间的类的互相访问,双亲委托模型加强了
Java
的安全,运行时包增加了对包可见成员的保护。
分享到:
相关推荐
本文将深入浅出地探讨JVM ClassLoader的工作原理和相关知识点。 首先,ClassLoader可以分为三种基本类型:Bootstrap ClassLoader、Extension ClassLoader和Application ClassLoader。Bootstrap ClassLoader是JVM...
【JVM运行机制详解】 Java虚拟机(JVM)是Java平台的核心组成部分,它负责执行...在《深入JVM内核—原理、诊断与优化》视频教程中,会详细讲解这些内容,并结合实际案例进行演示和实践,帮助开发者成为JVM领域的专家。
ClassLoader原理的理解对于深入学习Java和进行系统优化至关重要。这篇博文将带你深入了解ClassLoader的工作机制。 首先,我们来理解ClassLoader的基本概念。ClassLoader是一个抽象的概念,它是Java中的一个接口,...
在本课程中个,将详细介绍JVM的基本原理、组成以及工作方式,并配合实际案例,介绍相关的调优技巧。 课程大纲: 第一课 初识JVM JVM分类 Java语言规范 JVM规范 介绍JVM的基本知识和发展历史,并介绍了Java语言...
JVM组成及工作原理 JVM(Java Virtual Machine)是一种基于栈的虚拟机,它是Java程序的运行环境。JVM主要由两个子系统和两个组件组成。两个子系统分别是Classloader子系统和Executionengine子系统;两个组件分别是...
2. **类加载机制**:JVM使用类加载器(ClassLoader)将.class文件加载到内存中,类加载器体系结构包括Bootstrap ClassLoader、Extension ClassLoader和Application ClassLoader,它们分别负责加载不同的类库。...
### Java ClassLoader原理详解 #### 摘要 本文探讨了Java虚拟机(JVM)中的一个重要特性:动态类加载(Dynamic Class Loading)。这一机制为Java平台提供了强大的能力,允许在运行时安装软件组件,例如从网络下载...
### WebSphere ClassLoader原理 #### 一、概述 在探讨WebSphere Application Server v6中的ClassLoaders之前,我们首先简要回顾一下ClassLoaders的基本概念及其在Java虚拟机(JVM)中的作用。 **ClassLoaders**是...
JVM提供了三种类加载器:Bootstrap ClassLoader、Extension ClassLoader和Application ClassLoader,分别用于加载Java核心类库、扩展类库和应用程序类库。此外,JVM还支持自定义类加载器,以便于实现特定的加载逻辑...
在Java编程语言中,ClassLoader是核心组件之一,它负责加载类到JVM(Java虚拟机)中执行。本文将深入探讨ClassLoader的工作原理和类加载机制,帮助开发者理解这个至关重要的概念。 1. 类加载机制概述 Java的类加载...
在JVM的运行机制中,ClassLoader起着至关重要的作用。ClassLoader负责将类的.class文件加载到JVM中,使得Java程序能够运行。本文将深入探讨ClassLoader的工作原理,源码分析以及实际应用案例。 首先,我们需要理解...
1. JVM原理:JVM的工作原理涉及类加载器(ClassLoader)、类文件(ClassFile)、内存管理及垃圾收集机制。类加载器负责将.class文件加载到内存中,为程序的运行准备数据结构。内存管理涉及JVM内存区域,包括堆、栈、...
《深入JVM内核—原理、诊断与优化》是一本专为Java开发者和系统管理员精心编写的指南,旨在帮助读者全面理解Java虚拟机(JVM)的工作机制,掌握高效的性能诊断技巧,并能进行有效的优化实践。JVM是Java程序运行的...
JVM 原理讲解和调优 JVM(Java Virtual Machine,Java 虚拟机)是 Java 语言的核心组件,它是一个虚构出来的计算机,是通过在实际的计算机上仿真模拟各种计算机功能来实现的。JVM 的主要功能是将 Java 字节码转换为...
### JVM原理及调优 #### 一、JVM概述 JVM(Java Virtual Machine,Java虚拟机)是Java编程语言的基础,它作为一种软件层面的抽象计算机,能够在多种操作系统平台上执行Java字节码程序。Java编译器的目标是生成能够...
### JVM底层原理——类加载子系统详解 #### 一、引言 Java虚拟机(JVM)作为Java程序运行的基础环境,其内部结构复杂且功能强大。本文将基于“JVM底层原理课件PPT”中关于类加载子系统的介绍进行深入解析。类加载子...
《深入JVM内核——原理、诊断与优化》是一份深度探讨Java虚拟机核心机制、问题诊断和性能优化的专业资料。这份资料涵盖了JVM的各个方面,对于Java开发者来说,理解和掌握这些知识至关重要。 首先,我们要了解JVM...
了解JVM的工作原理对于优化Java应用程序性能、排查问题以及深入理解内存管理至关重要。以下是对JVM工作原理的详细阐述: 1. **类加载机制**:JVM在运行时动态加载类,这个过程包括加载、验证、准备、解析和初始化五...