Change Dir

先知cd——热爱生活是一切艺术的开始

统计

留言簿(18)

积分与排名

“牛”们的博客

各个公司技术

我的链接

淘宝技术

阅读排行榜

评论排行榜

JVM学习笔记(3)——连接模型(上)

很重要的内容,可能分几天记录

  1. jvm为每个装载的类和接口保存一份独立的常量池。
  2. 动态加载最常用的是Class.forName(),这个方法有两个重载版本:Class.forName(String name)和Class.forName(String name, boolean init, ClassLoader loader)。它们均内部调用了forName0(String name, boolean initialize,ClassLoader loader),这是个native方法。前者调用传递的参数是name、true和启动类加载器。name是要加载类的全限定名,init表明是否要初始化,如果这个类已经被初始化过,这样的加载即使init是true也不会被再初始化,loader是要加载的类加载器,null的话使用默认的启动类加载器。
  3. 另一种方式动态加载类就是ClassLoader.loadClass()方法,这个方法也是两个重载版本:ClassLoader.loadClass(String name)和ClassLoader.loadClass(String name, boolean resolve),其中前者调用了后者,resolve传递false,resolve表示是否在装载时执行该类的连接。
  4. loadClass不初始化类,而forName初始化类,因此如果是需要动态加载类,该类马上被用到那么应该初始化,loadClass只加载,有可能出问题,但是会有安全考虑。
  5. 常量池解析:上一篇日志也记录到了,在完成验证和准备后,要进入解析阶段,而解析主要做的就是解析常量池,把符号引用转为直接引用。
  6. 对常量池CONSTANT_Class_info的解析,主要解析类和接口的符号引用,有两种入口:1)数组类,指向数组类的符号引用最后解析为一个Class的实例,如果数组的元素类型是引用类型,虚拟机用当前类加载器解析类型,如果数组是基本类型,虚拟机会立即创建关于那个元素类型的新数组类,确定维数,然后创建Class实例表示这个类,由启动类加载器定义。2)非数组类,第一步,装载类型或者任何超类型,先确定引用类型已经被当前类装载器装载过,虚拟机保证每一个类装载器都只装载一个给定名字的类型,这个步骤只是确定类型是否被装载,期间可能抛出的异常有:NoClassDefFoundError,ClassNotFoundError,ClassFormatError,UnsupportedClassVersionError,LinkageError,ClassCircularityError,IncompatibleClassChangeError;第二步,检查访问权限,如果发起引用的类型没有访问被引用类型的权限,jvm抛出IllegalAccessError;第三步,校验类型,出错则抛出VerifyError;第四步,准备类型,前面讲过,就是为不同类型分配内存;第五步,可选的解析类型,第六步,初始化。
  7. 对常量池CONSTANT_Fieldref_info的解析,完成对Class_info的解析后,JVM按照一定顺序搜索字段:在被引用的类型中查找具有指定名字和类型的字段,找不到,则检查类型直接实现或扩展的接口,递归检查其超接口,如果还找不到,检查类型直接的超类,并递归检查其所有超类,如果找不到,则失败,抛出NoSuchFieldError异常。找到字段,但是没有访问权限,抛出IllegalAccessError异常。解析完后标记该常量池入口为已解析,并在数据中放入指向这个字段的直接引用。
  8. 对常量池CONSTANT_Methodref_info的解析,完成对Class_info的解析后,JVM按照一定顺序搜索方法:如果被解析类型是一个接口,虚拟机抛出IncompatibleClassChangeError异常,如果是个类,JVM检查被引用的类是否有一个方法符合指定的名字以及描述符,如果不符合,找该类的超类,并递归找所有超类,还是找不到,虚拟机检查该类是否直接实现了任何接口,并递归检查接口的超接口,还找不到,则抛出NoSuchMethodError异常,如果找到但是没有访问权限,抛出IllegalAccessError异常。解析完后标记常量池入口为已解析,并在数据中放入指向这个方法的直接引用。
  9. 对常量池CONSTANT_InterfaceMethodref_info的解析,完成对Class_info的解析后,JVM按照一定顺序在接口和它的超类型中搜索方法:如果被解析的类型不是接口是类,抛出IncompatibleClassChangeError异常,否则检查接口是否有符合指定名字和限定符的方法,如果没有,JVM检查接口的直接超接口并递归检查所有超接口以及java.lang.Object类来找,如果还没有,抛出NoSuchMethodError异常。解析完后标记常量池入口为已解析,并在数据中放入指向这个方法的直接引用。

posted on 2012-09-21 14:17 changedi 阅读(442) 评论(0)  编辑  收藏 所属分类: Java技术


只有注册用户登录后才能发表评论。


网站导航: