【转载】JVM类加载机制小结-阿里云开发者社区

开发者社区> javahongxi> 正文

【转载】JVM类加载机制小结

简介:
+关注继续查看

本文转载自http://shift-alt-ctrl.iteye.com/blog/1845137

 

一.类加载   

    虚拟机把class文件加载至内存之后,对字节码数据进行校验/解析/初始化等操作,最终形成可被VM直接使用的java类型,这就是虚拟机类加载机制.类的加载完全可以在运行时进行,这给VM提供了动态加载类提供了可行性.

    类生命周期过程大概分为:加载-->校验-->解析-->初始化-->使用-->卸载;类在被"使用"之前必须进行前4个阶段,其中初始化工作可以被延迟进行,直到类需要创建实例/static方法或属性被调用(非编译常量)/反射机制中使用类的成员(Member)时被触发.

  1. 加载:通过类的全限定名的方式获取class文件的字节流.事实上,加载器可以从任何类型文件(zip,jar,txt等)或者网络中获取class字节流.参见ClassLoader类
  2. 校验:检查加载至内存的字节流是否符合当前JVM的规范要求,字节流信息需要被当前JVM(考虑到JVM的版本问题)正确的识别,包括字节流的格式/字节码的语义(语法)/类的继承关系/变量的声明合法性等进行全面校验,如果校验成功,则表明此class字节流是安全的/没有被修改的/可以被正常使用的.
  3. 准备:准备阶段是一个过渡阶段,在类文件校验合法之后,将会得出类的结构图,此时有必要对类的属性(static)进行默认值设定,比如static int默认为0,即使指定了值.不过对于final类型的,将会以"常量"特例被处理,直接持有原始值.
  4. 解析:解析阶段是JVM将常量池中的符号引用转换成直接引用的过程.
  5. 初始化:到此为止,一个类的"前戏"工作基本结束,接下来就可以"服务"了,此时类的属性(static)将会被设定为用户指定的值(区别于准备阶段),而且还会执行类的static区块.同时也会连带执行父类的static区块和静态属性的值初始化.对于类的static区块在多线程环境中被同步执行,如果有多个线程同事执行static区块,事实上最终只会在有一个线程执行.

二.类加载器

    对于任意一个类,它的唯一性将有它的类加载器和其类型来决定;如果一个类被多个classLoader加载(最终执行load操作的classLoader必须不同),那么它们最终获得的class引用将不相等(即"!="),即使用==,equals(),instanceof,isInstance(),isAssignableFrom()都得不到预期的值,事实上可以简单的认为,他们是不同的"类"(类型).

  1. 引导类加载器:Bootstrap-classLoader,此类主要负责加载JAVA API,即处于$JAVA_HOME$\lib下的class文件,这些lib位置可以在外部通过-Xbootclasspath指定,但是此目录下的jar文件不能被重命名或者人为增加,否则将不能被正常加载;引导类加载器不能被java程序获得,尝试获得引导类加载器将返回null.
  2. 扩展类加载器:负责加载$JAVA_HOME$\lib\ext目录下的class,开发者可以人为的在此目录下添加jar文件,以便被此JVM之上的所有应用所收益.此加载器可以被程序获取,一般为classpath类加载器的父类.(sun.misc.Launcher$ExtClassLoader)
  3. 应用类加载器:Application ClassLoader,负责加载应用的classpatch下的所有class文件,其中ClassLoader.getSystemClassLoader()获得的就是此加载器.(sun.misc,Launcher$AppClassLoader);自定义类加载器的父加载器一般设定为它.

JVM并没有使用继承关系来组织这三种类加载器,而是采取了组合关系(即classLoader.setParent(...)).

    JVM类加载过程和类关系维护采取了"双亲委派模型":对于任何类加载器(包括自定义类加载器)对于指定类的加载,首先交付给"父-类加载器"查找或加载,如果父-类加载器已经加载则直接获取class引用,否则继续传递当前类加载器的父-类加载器,直到引导类加载器,如果此时引导类加载器也没有持有class信息,则抛出异常(异常信息只作为中断信号),此时当前类加载器(直接接收加载请求的类加载器,比如自定义类加载器)将会尝试加载类信息...通过这种"委派关系",能够巧妙的(当然不是最佳的手段)规避类被重复加载的可能.

 

三.编译与泛型

    java中的泛型,是伪泛型,只是简单的在API级别做了"模样",但是对于类的编译过程,则会导致泛型类型的擦除,即编译过程或者编译之后的文件中,最终泛型仍然以"原生类型"表示.即在运行时无法直接还原"泛型",java还支持了反射机制,为了让反射机制能够和"泛型"配合,那么java最终提供了Generic(例如GenericArrayType)和ParameterizedType来配合获得泛型(和参数化类--类型)的信息,这些信息虽然在编译时被擦除,但是元数据(metadata)仍然被有效的class文件中.

    例如:List<Integer>在编译之后,API级别上就成了List,"丢失"了参数化的信息.那么方法 void invoke(List<Integer> list) 和void invoke(List<String> list),那么将不能共存在一个类中,因为编译之后它们是一样的.(识别方法的特性,有方法签名 + 参数列表,而定);但是还有一中特例,如果方法的参数列表中或者返回值中或者当前类是参数化的,那么对于方法的返回值类型也参与了"方法标识";例如上述两个方法,如果第二个方法改成Integer invoke(List<String> list)或者<T> T invoke(List<T> list)将被成功编译.

版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

相关文章
淘宝 Android 端图片体验优化实践
淘宝 Android 端图片体验优化实践
7 0
flutter制作博客展示平台,现已支持 Web、macOS 应用、Android 和 iOS
Flutter Blog Theme using Flutter | Web, macOS, Android, iOS Flutter 最近发布了 Flutter V2.5.1,其性能得到了很大提升,支持 Web、macOS、Android 和 iOS。 这就是为什么今天我们使用在 Web、macOS 应用、Android 和 iOS 应用上运行的 flutter 创建响应式博客主题。 此外,我们创建了一个具有自定义悬停动画的动画网络菜单。 最后,您将学习如何使用 Flutter 制作响应式应用程序。
7 0
ECS使用感受
阿里云服务器初体验
5 0
Tomcat服务器目录结构
对于开发人员来说,经常会用到Tomcat服务器,它用起来简单,比较实用。 1.Tomcat的下载 1.请先确认你的JDK版本(在cmd窗口输入 java -version)
8 0
flutter项目迁移空安全
迁移 你的代码里大部分需要更改的代码,都是可以轻易推导的。例如,如果一个变量可以为空,它的类型需要 ? 后缀。一个不可以为空的命名参数,需要使用 required 标记。
4 0
Java线上问题排查神器Arthas实战分析
Java线上问题排查神器Arthas实战分析 是不是在实际开发工作当中经常碰到自己写的代码在开发、测试环境行云流水稳得一笔,可一到线上就经常不是缺这个就是少那个反正就是一顿报错抽风似的,线上调试代码又很麻烦,让人头疼得抓狂;而且debug不一定是最高效的方法,遇到线上问题不能debug了怎么办。原先我们Java中我们常用分析问题一般是使用JDK自带或第三方的分析工具如jstat、jmap、jstack、 jconsole、visualvm、Java Mission Control、MAT等。
11 0
高校学生参加飞天加速计划
linux与服阿里云服务器ECS, 阿里云服务器为提供了强大云计算能力。并且平台有很多开发者的使用教程,让我们新手也能很快上手去开发一些网站,希望更多的学生能够加入到阿里云,学习+实战让自己变得更强。
10 0
关于WebView 控件,你了解多少?
大家需要知道,不管什么技术,最终在 App 里面显示网页,一定需要一个网页引擎,这样才能解析网页。 通常情况下,App 内部会使用 WebView 控件作为网页引擎。这是系统自带的控件,专门用来显示网页。应用程序的界面,只要放上 WebView,就好像内嵌了浏览器窗口,可以显示网页。
3 0
跨平台技术栈
跨平台技术栈可以做到多平台支持,但是原理完全不同。 跨平台技术栈的框架,都是使用自己的语法编写页面,不使用 Web 技术,编译的时候再将其转为原生控件,或者使用自己的底层控件,生成原生 App。这样就完全解决了 Web 页面性能不佳的问题。下面介绍三个这样的框架。
3 0
冬季实战营第二期:Linux操作系统实战入门
第二期课程主要针对Linux操作系统入门的小白课程,本课程包含Linux基本命令,常用命令,文本搜索、文件搜索、用户管理、用户组、vim编辑器、系统命令等等。
8 0
+关注
javahongxi
京东技术 www.toutiao.im
33
文章
0
问答
文章排行榜
最热
最新
相关电子书
更多
《2021云上架构与运维峰会演讲合集》
立即下载
《零基础CSS入门教程》
立即下载
《零基础HTML入门教程》
立即下载