java类加载
类的生命周期(类加载过程)
LLIUU+VPR
加载(Loading)
链接(Linking)
验证(Verification)
准备(Preparation)
解析(Resolution)
初始化(Initialization)
使用(Using)
卸载(Unloading) 类
类加载器种类
BootstrapClassLoader:C++编写,负责加载java核心类库
Launcher.ExtClassLoader:Launcher中的内部类,parent == null
Launcher.AppClassLoader:Launcher中的内部类,parent == ExtClassLoader
用户自定义ClassLoader:继承自ClassLoader,parent == AppClassLoader
类加载机制
java中默认的类加载机制是双亲委派模式。
ClassLoader中关键的方法说明:
loadClass // 类加载入口,包含下面这些步骤
=> findLoadedClass => findLoadedClass0 // 先从缓存中查询一下,看看目标类是否已加载过
=> findBootstrapClassOrNull => findBootstrapClass // 用Bootstrap类加载器进行加载
=> findClass // 读取字节码文件,然后加载字节码文件
=> defineClass // 加载字节码文件
=> preDefineClass // 加载前的检查
=> defineClassSourceLocation // 定义类加载的路径
=> defineClass1/defineClass2 // 调用native方法加载类
=> postDefineClass //
=> resolveClass => resolveClass0
ClassLoader 部分源码:
package java.lang;
import java.io.InputStream;
...
public abstract class ClassLoader {
private final ClassLoader parent;
// -- Class --
protected Class> loadClass(String name, boolean resolve)
throws ClassNotFoundException
{
synchronized (getClassLoadingLock(name)) {
// First, check if the class has already been loaded
Class> c = findLoadedClass(name); // 缓存机制
if (c == null) {
long t0 = System.nanoTime();
try {
// 双亲委派机制
if (parent != null) {
c = parent.loadClass(name, false);
} else {
c = findBootstrapClassOrNull(name);
}
} catch (ClassNotFoundException e) {
// ClassNotFoundException thrown if class not found
// from the non-null parent class loader
}
if (c == null) {
// If still not found, then invoke findClass in order
// to find the class.
long t1 = System.nanoTime();
c = findClass(name);
// this is the defining class loader; record the stats
sun.misc.PerfCounter.getParentDelegationTime().addTime(t1 - t0);
sun.misc.PerfCounter.getFindClassTime().addElapsedTimeFrom(t1);
sun.misc.PerfCounter.getFindClasses().increment();
}
}
if (resolve) {
resolveClass(c);
}
return c;
}
}
// findClass由子类去实现
protected Class> findClass(String name) throws ClassNotFoundException {
throw new ClassNotFoundException(name);
}
// defineClass 加载类
protected final Class> defineClass(String name, byte[] b, int off, int len,
ProtectionDomain protectionDomain)
throws ClassFormatError
{
protectionDomain = preDefineClass(name, protectionDomain);
String source = defineClassSourceLocation(protectionDomain);
Class> c = defineClass1(name, b, off, len, protectionDomain, source);
postDefineClass(c, protectionDomain);
return c;
}
private ProtectionDomain preDefineClass(String name,
ProtectionDomain pd)
{
if (!checkName(name))
throw new NoClassDefFoundError("IllegalName: " + name);
// Note: Checking logic in java.lang.invoke.MemberName.checkForTypeAlias
// relies on the fact that spoofing is impossible if a class has a name
// of the form "java.*"
if ((name != null) && name.startsWith("java.")) {
throw new SecurityException
("Prohibited package name: " +
name.substring(0, name.lastIndexOf('.')));
}
if (pd == null) {
pd = defaultDomain;
}
if (name != null) checkCerts(name, pd.getCodeSource());
return pd;
}
private String defineClassSourceLocation(ProtectionDomain pd)
{
CodeSource cs = pd.getCodeSource();
String source = null;
if (cs != null && cs.getLocation() != null) {
source = cs.getLocation().toString();
}
return source;
}
private void postDefineClass(Class> c, ProtectionDomain pd)
{
if (pd.getCodeSource() != null) {
Certificate certs[] = pd.getCodeSource().getCertificates();
if (certs != null)
setSigners(c, certs);
}
}
private native Class> defineClass0(String name, byte[] b, int off, int len,
ProtectionDomain pd);
private native Class> defineClass1(String name, byte[] b, int off, int len,
ProtectionDomain pd, String source);
private native Class> defineClass2(String name, java.nio.ByteBuffer b,
int off, int len, ProtectionDomain pd,
String source);
protected final void resolveClass(Class> c) {
resolveClass0(c);
}
private native void resolveClass0(Class> c);
private Class> findBootstrapClassOrNull(String name) {
if (!checkName(name)) return null;
return findBootstrapClass(name);
}
// return null if not found
private native Class> findBootstrapClass(String name);
protected final Class> findLoadedClass(String name) {
if (!checkName(name))
return null;
return findLoadedClass0(name);
}
private native final Class> findLoadedClass0(String name);
// -- Resource --
...
// -- Hierarchy --
...
// -- Package --
...
// -- Native library access --
...
// -- Assertion management --
...
}
双亲委派