五:java类加载

Java 类型的加载和链接都是在运行期间,这样可能会有性能开销,可是却能提供动态扩展的语言特性。
git

解析可能在初始化以后进行数组

vm规范规定了四个点必须对类进行初始化:网络

  1. 遇到new ,getstatic,putstatic, invokestatic几个指令的时候。也就是new, 使用设置静态变量,引用静态方法的时候 访问静态变量只会形成当前类的初始化,不会初始化子类,这里还要注意,对于被final修饰、在编译器已经放入常量池的静态属性不会触发初始化。 new 数组是不会初始化类的
  2. reflect包的方法对类进行反射调用的时候
  3. 初始化时要先初始化父类
  4. 虚拟机启动时要指定主类,主类会先初始化

过程

加载

1. 根据全名获取二进制字节流                没有指明流的来与,因而能够是jar包,网络,动态代理在运行时生成
2. 在方法区生成该类的运行时数据结构
3. 在堆上建立Class对象,做为对方法区数据访问入口

验证

要求知足字节码格式规范等

准备

为类变量分配内存并设定初始值的阶段,  不涉及实例变量,都在方法区进行。

解析

将常量池内的符号引用替换为直接引用的过程。
符号引用就是字面量, 没有指向实际的内存,只是表示知道这个类有这个引用,但具体引用到哪里还不知道
直接引用,  是链接了实际目标的符号引用

初始化

执行类client()方法的过程, 由编译器收集的类变量赋值动做和static方法块合并成的。
虚拟保证client是顺序执行的,所以要注意若是static预发快中有死循环会形成阻塞

类加载器

 

  1. 工做流程: 收到加载请求后,交给父加载器去完成, 父完不成才会尝试本身完成。 以下是个过程 Class c = findClass(name); if(c == null){ c = parent.loadClass(name); } if(c == null){ // 父不行了,本身来 c = findClass(name) } return c;
  2. 破坏双亲委派
    1. JNDI 双亲委派解决不了基础类须要调用用户代码的状况 JNDI服务由启动加载器加载,可是其用到的接口类却由各个厂商提供,启动加载器就会找不到,引入了线程上下文加载器,须要使用Thread.setContextClassLoader()进行设置。JNDI就是用了这个加载器
    2. OSGI, 每一个boundler一个类加载器,import的类委托给export的类加载器去加载。
相关文章
相关标签/搜索