JVM系列之初识JVM《二》
从前面的博文中,我们了解到Java的跨平台性以及JVM的生命周期以及工作原理,接下来我们来了解JVM的加载系统等。
JVM架构图基础介绍
将JVM划分为三个主要的子系统
类装载子系统(Class Loader Subsystem)
运行时数据区(Runtime Data Areas)
执行引擎(Execution Engine)
类装载子系统
Java的动态类装载功能是由类装载子系统实现,可以装载,连接,初始化文件
- 加载:功能是加载类,共有三种类加载器,Boot Strap Class Loader,Extension Class Loader和Application Class Loader
- 链接:
验证:字节码验证器将验证生成字节码是否正确,如果验证失败,将得到验证错误信息
准备:将所有的静态变量,内存被分配并初始值
解析:将所有的符合内存引用替换为来自方法区域的原始引用
- 初始化
静态变量都将被赋值,静态代码块会执行
运行时数据区域(JMM)
方法区:类级别的数据,静态变量存储位置(线程共享)
堆区:对象及实例变量和数据存储的位置(线程共享)
虚拟机栈:线程执行过程中的堆栈信息(线程私有)
本地方法栈:和JNI操作的堆栈信息(线程私有的)
程序计数器:执行程序过程记录当前指令的地址(线程私有)
执行引擎
将运行时数据区域内的字节码交由执行引擎来执行,执行引擎读取字节码并逐行来执行
类加载机制
Java的源代码经过编译生成相应的.class文件,也就是字节码文件,而字节码文件有通过JVM中解释器,编译成特定机器上的机器码
Java源文件-》编译-》字节码文件
字节码文件-》JVM(解释器)-》机器码
类加载时机
虚拟机规范中严格规定有且只有5种情况需要立即对类进行初始化(class加载到JVM中)
- 创建对象实例:new对象的实例,会对类做初始化,前提这个类没有被初始化
- 通过class文件反射创建对象
- 调用类的静态属性或为静态属性赋值或者是调用类的静态方法 (Person.talk())
- 初始化一个类的子类,使用子类的时候先初始化父类
- Java虚拟机启动时被标记为启动类的类,比如main方法所在的类
注:Java类的加载是动态过程,并不是一次性将所有的类加载后在运行,而是要保证程序运行的基础类完全加载到JVM,至于其他的类,则在需要的时候才能进行加载,为了节省内存开销
不会进行初始化的情况:
- 在同一个类加载器下一个类只能被初始化一次,已经被初始化的类就不必要初始化了
- 在编译的时候能确定下来的静态变量,不会对类进行初始化,比如final修饰的静态变量
类加载器
负责将字节码文件加载到内存
类加载器介绍
各个加载器的责任:
Bootstrap ClassLoader(启动类加载器):负责加载$JAVA_HOME中/jre/lib/rt.jar里的所有问class
Extension ClassLoader(扩展类加载器):负责加载Java平台下扩展功能的一些Jar包。包括$JAVA_HOME/jre/lib/*.jar文件
APP ClassLoader(应用类加载器):负责加载classpath中指定的jar和目录中的class
User ClassLoader(自定义类加载器):
未完待续。。。。。。