菜鸟入坑》JVM如何加载类
2018-03-10 15:26
155 查看
1.JVM是如何实现类的加载?
java代码经过各种编译器就编译成了.class文件。哪JVM是如何加载.class文件的呢?
首先ClassLoader会把.class文件加载到JVM内存中。之后会对它进行数据校验,转化解析以及初始化。最终形成了可以被JVM直接使用的java类型,这就是类的加载。
在类被加载的时候JVM就确定了类对象的内存对象,给对象分配了内存空间。在java的世界里,类的加载,链接和初始化都是在运行期间完成的。
流程图:
2.类的生命周期
类的生命周期主要分为七个阶段。加载,验证,准备,解析,初始化,使用,卸载。
小知识:
当遇到new,getstatic,putstatic,invokestatic这几个字节码指令时,如果类没有初始化过,必须先初始化。初始化时,父类没有初始化先初始化父类。指定了main方法的类(主类)优先初始化。
2.1类的加载的生命周期:
加载,验证,准备,解析,初始化。五个阶段。
2.2不同阶段多做了什么?
A.加载阶段:
这个阶段是通过类加载器完成的,有兴趣的可以研究一下ClassLoader,我就不说了。
主要是做了以下几个操作:
通过类的全限定名获取定义此类的二进制自己流
将字节流中代表静态存储结构转化为方法区运行时的数据结构。
在内存中产生一个代表这个类的class对象,作为方法区访问的入口。
注意:这里只针对非数组类。其实加载阶段,开发者可以自定义一个类加载器去完成,即重写ClassLoader的loadClass方法,网上也有很多例子,但是实际开发中一般不使用。
B.验证阶段:
验证是为了确保class文件的字节流包含的信息符合当前虚拟机的要求,不危害到虚拟机,因为class文件可以通过很多手段处理得到,不一定是java源码编译生成的。
主要是以下操作:
文件格式验证。
元数据验证
字节码验证
符号引用验证
C.准备阶段
准备是为了给类的变量分配内存并设置类变量初始值(被static修饰的变量),这些变量所使用的内存将在方法区中进行分配。(对成员变量,类变量,实例变量概念模糊的,可以看一下:菜鸟入坑》成员变量、实例变量、类变量、成员方法、实例方法、类方法的区别这篇文件,我大概介绍了一下。)
注意:这里的初始值通常情况下是零值。例如一个类变量为public static int value = 10;类变量在准备阶段初始值是0不是12.赋值为12是初始化阶段。
基本类型的零值表:
基本数据类型的零值
D.解析阶段
解析阶段JVM会将常量池的符合引用代替为直接引用。
符合引用和直接引用的区别:
符号引用存在于.class文件中,不在内存中,于JVM内存没有关系。以一组符号来描述目标引用。
直接引用存在于JVM内存中。
E.初始化阶段
初始化阶段就是执行类构造器<clinit>()方法的过程。在初始化过程具体怎么操作。菜鸟入坑》类的初始化认识这篇文件介绍了一下。
最后各位大牛发现了不足请指出,谢谢!
java代码经过各种编译器就编译成了.class文件。哪JVM是如何加载.class文件的呢?
首先ClassLoader会把.class文件加载到JVM内存中。之后会对它进行数据校验,转化解析以及初始化。最终形成了可以被JVM直接使用的java类型,这就是类的加载。
在类被加载的时候JVM就确定了类对象的内存对象,给对象分配了内存空间。在java的世界里,类的加载,链接和初始化都是在运行期间完成的。
流程图:
2.类的生命周期
类的生命周期主要分为七个阶段。加载,验证,准备,解析,初始化,使用,卸载。
小知识:
当遇到new,getstatic,putstatic,invokestatic这几个字节码指令时,如果类没有初始化过,必须先初始化。初始化时,父类没有初始化先初始化父类。指定了main方法的类(主类)优先初始化。
2.1类的加载的生命周期:
加载,验证,准备,解析,初始化。五个阶段。
2.2不同阶段多做了什么?
A.加载阶段:
这个阶段是通过类加载器完成的,有兴趣的可以研究一下ClassLoader,我就不说了。
主要是做了以下几个操作:
通过类的全限定名获取定义此类的二进制自己流
将字节流中代表静态存储结构转化为方法区运行时的数据结构。
在内存中产生一个代表这个类的class对象,作为方法区访问的入口。
注意:这里只针对非数组类。其实加载阶段,开发者可以自定义一个类加载器去完成,即重写ClassLoader的loadClass方法,网上也有很多例子,但是实际开发中一般不使用。
B.验证阶段:
验证是为了确保class文件的字节流包含的信息符合当前虚拟机的要求,不危害到虚拟机,因为class文件可以通过很多手段处理得到,不一定是java源码编译生成的。
主要是以下操作:
文件格式验证。
元数据验证
字节码验证
符号引用验证
C.准备阶段
准备是为了给类的变量分配内存并设置类变量初始值(被static修饰的变量),这些变量所使用的内存将在方法区中进行分配。(对成员变量,类变量,实例变量概念模糊的,可以看一下:菜鸟入坑》成员变量、实例变量、类变量、成员方法、实例方法、类方法的区别这篇文件,我大概介绍了一下。)
注意:这里的初始值通常情况下是零值。例如一个类变量为public static int value = 10;类变量在准备阶段初始值是0不是12.赋值为12是初始化阶段。
基本类型的零值表:
数据类型 | 零值 | 数据类型 | 零值 |
int | 0 | boolean | false |
long | 0L | float | 0.0f |
short | 0 | double | 0.0d |
char | '\u0000' | reference | null |
byte | 0 |
解析阶段JVM会将常量池的符合引用代替为直接引用。
符合引用和直接引用的区别:
符号引用存在于.class文件中,不在内存中,于JVM内存没有关系。以一组符号来描述目标引用。
直接引用存在于JVM内存中。
E.初始化阶段
初始化阶段就是执行类构造器<clinit>()方法的过程。在初始化过程具体怎么操作。菜鸟入坑》类的初始化认识这篇文件介绍了一下。
最后各位大牛发现了不足请指出,谢谢!
相关文章推荐
- JVM如何加载一个类的过程,双亲委派模型中有哪些方法?
- 理解jvm如何加载类
- 如何显示JVM(JAVA虚拟机)类加载顺序
- JVM如何加载一个类的过程
- Java中class是如何加载到JVM中的(Class.forName("name")和ClassLoader.loadClass("name")的区别)
- jvm是如何加载class
- Java中class是如何加载到JVM中的(Class.forName(&quot;name&quot;)和ClassLoader.loadClass(&quot;name&quot;)的区别)
- JNI官方规范中文版——如何把一个JVM嵌入到本地程序中 native程序中加载jvm
- JVM如何加载一个类的过程
- 如何显示JVM(JAVA虚拟机)类加载顺序
- 如何判断框架(iframe)已被加载完毕?
- JVM——类加载机制
- cocos2d-x的lua脚本如何加载Cocostudio制作的UI文件
- Windows2008R2中如何取消增强的IE设置? 可加载一些无法加载的js,解决ie冲突问题打开Windows2008服务器管理器,如图
- 如何正确的加载和执行 JavaScript 代码
- JS插件如何加载
- 如何判断flash是否加载完
- 进程环境之共享库以及如何区分静态库、共享库和动态加载库
- sharpdevelop中如何加载addin文件
- bochs下如何加载和调试jos内核的过程: