目录
一.jvm加载class步骤
1、装载class文件:查找和导入class文件
2、链接:检查载入的class文件数据的正确性、为类的静态变量分配内存空间、将符号引用转换为直接引用
3、初始化:初始化静态变量、静态块
二.类加载器
类加载器负责将class文件加载到内存中。
为了保证jre核心类以及扩展类的安全,避免基础类被有相同名称的用户自定义类覆盖,jvm采用了双亲委派机制加载类。
双亲委派机制就是加载器不直接加载类,首先委派给父加载器在其加载类库范围内是否有该类,若没有加载器再进行加载。jvm默认有三种加载器Bootstrap类加载器、Extension类加载器、Application类加载器,可以通过下列代码获取加载器。
XXX.class.getClassLoader()
Bootstrap类加载器:负责加载tr.jar中的类,该包中的类通过XXX.class.getClassLoader()获取的加载器为null,因为该加载器是由C++语言编写。
Extension类加载器:负责加载jre/lib/ext目录下和java.ext.dirs系统属性定义的目录下的类,该加载器为Bootstrap类加载器的子加载器。
Application类加载器:负责从classpath环境变量中加载某些应用相关的类,该加载器为Extension类加载器的子加载器。
三.内存分配堆、栈、方法区
堆:存储全部对象
栈:每个线程开通一个栈区,存放基本类型本身、引用类型在堆中的地址
方法区(静态区):用于存放所有class和static变量,方法区时jvm规范中的一个概念,不同的jvm实现的方式不同,Hotspot使用比较广泛,Hotspot中将方法区放在永久代中,永久代是Hotspot虚拟机特有的概念。
四.堆结构
hotspot堆结构如上图,堆被分为年轻代、年老代、永久代。
年轻代:默认分为三个区,一个eden区、两个survivor区,survivor区的个数可以进行配置。大部分对象在eden区生成,当eden区满时,还存活的对象会被复制到其中一个survivor区,当这个survivor区满时,这个survivor区中仍然存活的对象将被复制到另一个survivor区,第二个survivor区也满时,从第一个survivor区来的对象会被复制到年老代。survivor的两个区时对称的没有先后关心,所以同一个区中可能同时存在从Eden区和另一个Survivor过来的对象,并且Survivor区总有一个为空。
年老代:年轻代中经过N次垃圾回收后仍然存活的对象会存在年老代,可以看作年老代存放生命周期比较长的对象。
永久代:用于存放静态文件,比如class类、方法、static变量等。
注:java8以后废除了永久代,将静态文件存放在元空间中。永久代和元空间都是hotspot方法区的实现方式,永久代需要占用jvm的堆内存,而元空间使用的是外部内存。为什么废除永久代请移步https://www.cnblogs.com/yulei126/p/6777323.html。
持续更新中.........