2-JVM-类加载

加载过程
  • 装载load
    • 查找并加载类的二进制数据
  • 链接link
    • 验证
    • 确保被加载类的正确性和合法性,防止高手伪造恶意的非法class文件
    • 准备
    • 为类的静态变量分配内存,并将其初始化为默认值
    • 解析
    • 符号引用 - 直接引用
  • 初始化initialize
    • 为类的静态变量赋予正确的初始值
    • 静态代码块
初始化
  • 引起类初始化情况
    • 称为主动引用,被动引用不会引发初始化
    • new一个对象,new字节码指令
    • 访问类或接口的静态变量,或对类静态变量赋值,getstatic,putstatic(final修饰,编译期已进入常量池的除外)
    • 调用类的静态方法,invokestatic
    • 反射调用,如Class.forName(“类全限定名”)
    • 初始化子类前,会先初始化父类
    • JVM启动时标明的启动类
  • 初始化步骤
    • 若未装载和链接,则先装载和链接
    • 假设存在直接父类且直接父类还未初始化,则初始化直接父类(接口呢???)
    • 依次执行初始化语句(static变量和static语句块)
说明
  • 类加载的最终产物是位于堆区(还是方法区???)中的Class对象,Class对象封装了类在方法区内的数据结构,向程序员提供了访问方法区内数据结构的接口
  • 加载源
    • 本地文件系统
    • 通过网络下载class文件
    • 从zip和jar等归档文件中加载
    • 专有数据库中提取
    • 动态编译java源文件
类加载器
  • 架构
    • Bootstrap ClassLoader
    • JRE/lib/rt.jar
    • -Xbootclasspath指定的jar包
    • C++写的
    • Extention ClassLoader
    • JRE/lib/ext/*.jar
    • -Djava.ext.dirs指定目录下的jar包
    • App ClassLoader(System ClassLoader)
    • classpath
    • -Djava.class.path所指定目录下的类和jar包
    • Custom ClassLoader(User Defined Classloaders)
    • 继承java.lang.ClassLoader,自定义类加载器
  • 双亲委派
    • 检查类是否已被加载:自底向上
    • 加载类:自顶向下
Faster Class Loading
  • A feature called Class Data Sharing (CDS) was introduce in HotSpot JMV from version 5.0. During the installation process of the JVM the installer loads a set of key JVM classes, such as rt.jar, into a memory-mapped shared archive. CDS reduces the time it takes to load these classes improving JVM start-up speed and allows these classes to be shared between different instances of the JVM reducing the memory footprint.
Classloader Reference
  • All classes that are loaded contain a reference to the classloader that loaded them. In turn the classloader also contains a reference to all classes that it has loaded.
相关源码
# Class
public final class Class<T> implements java.io.Serializable, GenericDeclaration, Type, AnnotatedElement

@CallerSensitive
public static Class<?> forName(String className) throws ClassNotFoundException {
    Class<?> caller = Reflection.getCallerClass();
    return forName0(className, true, ClassLoader.getClassLoader(caller), caller);
}

private static native Class<?> forName0(String name, boolean initialize, ClassLoader loader, Class<?> caller) throws ClassNotFoundException;

# ClassLoader
public abstract class ClassLoader

public Class<?> loadClass(String name) throws ClassNotFoundException {
    return loadClass(name, false);
}

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);//这个方法在ClassLoader里没有实现,而是简单的抛出异常,可以看下javassist.Loader中的实现)
                // 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;
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值