记录我的学习过程:类加载

 类加载机制

JVM把class文件加载到内存,并对数据进行校验、解析和初始化,最终形成 JVM可以直接使用的Java类型的过程。

加载 

• 将class文件字节码内容加载到内存中,并将这些静态数据转换成方法区中的运行时数据结构,在堆中生成一个代 表这个类的java.lang.Class对象,作为方法区类数据的访问入口。 这个过程需要类加载器参与。


链接  

将Java类的二进制代码合并到JVM的运行状态之中的过程 

• 验证: – 确保加载的类信息符合JVM规范,没有安全方面的问题。 

• 准备: – 正式为类变量(static变量)分配内存并设置类变量初始值的阶段,这些内存都将在方法区中进行分配

 • 解析 – 虚拟机常量池内的符号引用替换为直接引用的过程

初始化 

• 初始化阶段是执行类构造器()方法的过程。类构造器()方法是由编译器自动收集 类中的所有类变量的赋值动作和静态语句块(static块)中的语句合并产生的。

 • 当初始化一个类的时候,如果发现其父类还没有进行过初始化、则需要先出发其父类的初始化 

• 虚拟机会保证一个类的()方法在多线程环境中被正确加锁和同步。

• 类的主动引用(一定会发生类的初始化) 

– new一个类的对象 

– 调用类的静态成员(除了final常量)和静态方法

 – 使用java.lang.reflect包的方法对类进行反射调用 

– 当虚拟机启动,java Hello,则一定会初始化Hello类。说白了就是先启动main方法所在的类 

– 当初始化一个类,如果其父类没有被初始化,则先会初始化他的父类

• 类的被动引用(不会发生类的初始化) 

– 当访问一个静态域时,只有真正声明这个域的类才会被初始化 

–  通过子类引用父类的静态变量,不会导致子类初始化 

– 通过数组定义类引用,不会触发此类的初始化

 – 引用常量不会触发此类的初始化(常量在编译阶段就存入调用类的常量池中了)

• 引导类加载器(bootstrap class loader) 

– 它用来加载 Java 的核心库(JAVA_HOME/jre/lib/rt.jar,或sun.boot.class.path路径下的 内容),是用原生代码来实现的,并不继承自 java.lang.ClassLoader。 

– 加载扩展类和应用程序类加载器。并指定他们的父类加载器。

 • 扩展类加载器(extensions class loader) 

– 用来加载 Java 的扩展库(JAVA_HOME/jre/ext/*.jar,或java.ext.dirs路径下的内容) 。 Java 虚拟机的实现会提供一个扩展库目录。该类加载器在此目录里面查找并加载 Java 类。

 – 由sun.misc.Launcher$ExtClassLoader实现

 • 应用程序类加载器(application class loader) 

– 它根据 Java 应用的类路径(classpath, java.class.path 路径下的内容)来加载 Java 类。 一般来说,Java 应用的类都是由它来完成加载的。 

– 由sun.misc.Launcher$AppClassLoader实现 

• 自定义类加载器

 – 开发人员可以通过继承 java.lang.ClassLoader类的方式 实现自己的类加载器,以满足一些特殊的需求。

你可能感兴趣的:(记录我的学习过程:类加载)