五:java类加载

Java类加载机制详解

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

解析可能在初始化之后进行

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

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

过程

加载

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

验证

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

准备

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

解析

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

初始化

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

类加载器

jvm-3.png

 

  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的类加载器去加载。

转载于:https://my.oschina.net/u/1034481/blog/824004

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值