JVM和类加载过程
1. JVM内存和操作系统内存关系
操作系统内存也有堆和栈。操作系统的栈由操作系统自己管理。操作系统的堆是开放的。
JVM的内存是操作系统堆中的一块区域。
对于操作系统来说,jvm只是一个普通的程序。
对于java程序来说,jvm是运行java程序的载体。
换言之,类加载过程,其实就是把在操作系统中编译完成的.class文件转换为jvm可识别的程序的过程。
2. JVM结构图
方法区:用于存储虚拟机加载的:静态变量+常量+类信息+运行时常量池;
堆:堆区主要用于存放对象实例及数组,所有new出来的对象都存储在该区域;
虚拟机栈:虚拟机栈占用的是操作系统内存,每个线程对应一个虚拟机栈,它是线程私有的;存放一些程序运行期间必要的东西,比如存储局部变量表、动态链接、操作数和方法出口等;
本地方法栈:本地方法栈用于支持native方法的执行,存储了每个native方法的执行状态;
程序计数器:JVM在解释字节码(.class)文件时,存储当前线程执行的字节码行号。
3. 类加载过程
(1)将class文件字节码内容加载到内存中,并将这些静态数据转换成方法区中的运行时数据结构,在堆中生成一个代表这个类的java.lang.Class对象,作为方法区类数据的访问入口,这个过程需要类加载器参与。
(2)分为三个阶段:
1)验证阶段:验证文件的安全性,防止对jvm本身造成危害;
2)准备阶段:正式为类变量(static变量)分配内存并设置类变量初始值
3)解析阶段:虚拟机常量池的符号引用替换为字节引用过程
(3)执行类构造器初始化类对象;
4. 由类加载过程延伸的问题
(1)类加载器?
虚拟机提供了3种类加载器:
启动类加载器:主要加载的是JVM自身需要的类,这个类加载使用C++语言实现的,是虚拟机自身的一部分;
扩展类加载器:负责加载JAVAHOME路径下的jdk中的一些类库;
系统类加载器:负责加载CLASSPATH路径下的应用程序。
(2)jvm以什么样的方式加载一个类
采用的是按需加载的方式,也就是说当需要使用该类时才会将它的class文件加载到内存生成class对象,而且加载某个类的class文件时,Java虚拟机采用的是双亲委派模式即把请求交由父类处理,它一种任务委派模式。 那么,一起来理解下双亲委派模式:
双亲委派模式要求除了顶层的启动类加载器外,其余的类加载器都应当有自己的父类加载器,请注意双亲委派模式中的父子关系并非通常所说的类继承关系,而是采用组合关系来复用父类加载器的相关代码。
双亲委派模式的好处是避免了一个类会被重复加载。
(3)jvm什么时候决定加载一个类?
1)创建对象就会触发加载;
2)引用了该类的静态属性、方法都会触发类的加载;
4)初始化子类也会导致父类被加载;
(4)java中创建对象的几种方式?
1) new对象
2) 用反射创建对象
3) 克隆对象
4) 序列化
参考博客: