JVM虚拟机基础 JVM虚拟机结构
vm的整体结构大致如下:
类加载器:类加载器用来加载Java类到JVM虚拟机中,源代码程序.java文件在经过编译器编译之后就被转换成字节代码.class文件,类加载器负责读取字节代码,并转换成java.lang.Class类的一个实例。
运行时数据区
元数据区:JDK1.8开始的说法,之前称为方法区Method-Area,存储已被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等数据。
堆区:所有线程共享的一块内存区域,虚拟机启动时被创建用来存放对象实例。
JVM栈:可以参考了解栈的数据结构,存放Java方法执行的内存模型,在Java开发中,一个功能实现需要多个子程序方法配合,程序执行时跳往子程序前,会将下个指令的地址存到堆栈中,直到子程序执行完后再将地址取出,退回到原来的程序中。
本地方法栈:本地方法栈和虚拟机栈的功能类似,为JVM调用native方法时服务。
程序计数器:相对较小的一块内存空间,作用可以理解是当前线程所执行的字节码的行号指示器。
执行引擎:Java虚拟机最核心的组成部分,输入的是字节码,处理过程是字节码解析,输出执行结果
生命周期这里说的JVM生命周期,指JVM执行Java程序时的周期:
启动初始化:启动时通过引导类加载器创建初始类完成;
程序执行:从main方法开始,执行Java程序,直到程序执行完结束;
虚拟机退出:程序正常执行结束,或者发生异常、错误等而造成终止,也可以调用exit退出方法;
HotSpot虚拟机HotSpot是Java体系下使用最多的虚拟机,它结合了最新的内存模型,垃圾收集器和自适应优化器,为使用许多先进技术的Java应用程序提供了最佳性能。
JVM类加载机制 类加载简介类的加载机制是指把编译后的.class类文件的二进制数据读取到内存中,并为之创建一个java.lang.Class对象,用来封装类在元数据空间的数据结构。
类在JVM中的生命周期为:加载,连接,初始化,使用,卸载。不过这里只重点描述加载,连接,初始化这三个过程
加载过程基于一张图看类加载子系统的细节流程:
过程描述:加载阶段需要完成以下三个过程:
通过类的全限定名来获取其定义的二进制字节流;
将字节流所代表的静态存储结构转化为云数据空间的运行时数据结构;
在堆Heap中生成一个代表这个类的java.lang.Class对象,作为对元数据空间中这些数据的访问入口;
类加载器:
引导类加载器:Bootstrap-ClassLoader基于C/C++实现,负责加载Java的核心类库JAVA_HOME\jre\lib\rt.jar,该加载器不继承自ClassLoader抽象类,并且只加载包名为java、javax、sun等开头类,一次保证对核心源码的保护。
扩展类加载器:Extension-ClassLoader,基于Java语言,由sun.misc.Launcher$ExtClassLoader实现,派生于ClassLoader抽象类,从java.ext.dirs系统变量指定的路径中的加载类库,或者JDK安装目录jre\lib\ext目录下加载。
系统类加载器:Application-ClassLoader,基于Java语言,由sun.misc.Launcher$ExtClassLoader实现,它负责加载环境变量ClassPath指定的类库,如果在应用程序中没有自定义类加载器,一般情况下作为程序中默认的类加载器。
2.连接阶段:验证:目的在于确保Class文件的字节流中包含的信息符合当前虚拟机的要求,保证加载类的正确性,不会危害虚拟机自身的安全,主要包括四种检验动作:
文件格式验证:验证字节流是否符合Class文件格式的规范;
元数据验证:确保其描述的信息符合Java语言规范的要求;
字节码验证:确定程序语义是符合逻辑的;
符号引用验证:确保解析动作能正确执行。
准备:为类的静态变量分配内存,并初始化为默认值,这时候进行内存分配的仅包括类变量(static)修饰,不包括(final-static)修饰的,这里也不会为实例变量分配初始化,实例变量会随着对象一块分配到Java堆中。