Java基础复习-JVM
Java基础复习-JVM
JVM是指Java Virtual Machine,是将字节码文件.class编译成电脑可以运行的文件,是独立虚拟机,兼容各种操作系统,是实现java跨平台的重要部分。
1.JVM内存模型

如上图,其中下面的大方块则代表了JVM
JVM的内存模型可以分为五个主要部分,分别是方法区、堆,虚拟机栈、本地方法栈和程序计数器。其中堆和方法区是被所有线程共享的,而栈和PCR是由线程私有的。
堆的进一步分类

堆区是分配内存最大的一部分(初始默认分配物理内存的1/64,最大允许分配物理内存的1/4),用于储存实例对象,因为大部分java对象生存周期较短,从提高垃圾回收性能的角度来说,堆会被进一步分为四个部分(如上图)
首先是两个大部分,新生代、老年代,这两个部分对应了已经生存了不同周期的对象(即经历一定次数垃圾回收后生存情况不同的对象)
新生代又可进一步划分为Eden区、toSurvivor区、fromSurvivor区,默认情况下这三个分区的比例是8:1:1,其中两个Survior区其中必定会有一个是空闲的(会交替),所以其中90%内存是可用的
垃圾回收GC
垃圾回收分为三种回收操作,Minor GC, Major GC, Full GC,执行频率依次下降,执行时间依次上升
Minor GC是新生代GC,Major是老年代GC,Full GC是对整个堆空间的GC
Eden区是创建新对象的内存区域,当Eden区空间不足时,会进行一次Minor GC,其中存活后的对象会被移动到其中一个Survivor区(如果能被Survivor区接受),这个对象对应的年龄也会增加1。当年龄到达一定大小(默认15),这个对象就会晋升到老年代中。
下面是几种回收操作的触发条件:
Minor GC: Eden区满,新创建对象大小超出Eden区剩余空间
Major GC和Full GC: 这两种回收操作一般是同时发生的,触发条件比较多:
- 1.晋升到老年代的对象平均大小超出老年代剩余空间
- 2.Minor GC后存活的对象超出老年代剩余空间
- 3.调用System.gc()申请GC
- 4.向堆内分配大对象
判断对象存活情况
(1).引用计数法
若一个对象不被任何引用指向,认为是垃圾。这种算法无法检测到环的情况,通常不被使用。
(2).可达性分析法
首先确定一个GC Roots,可以是虚拟机栈中引用的对象、方法区中引用的对象等
通过GC Roots向下搜索,其路径形成引用链,若一个对象无法通过任何引用链到达GC Roots时被视为垃圾,可以解决环形引用问题,是虚拟机常用算法
GC算法
(1).标记-清除算法
为每一个对象存储一个标记位,存储对象的生存情况。
第一个阶段是标记阶段,会为每个对象进行生存情况的检查,并对标记位进行更新。第二个阶段是清除阶段,会对死亡对象进行清除。
缺点是需要挂起,效率较低,导致内存碎片。通常用于老年代的GC。
(2).标记-整理算法
在标记-清除的基础上改进了内存碎片问题。
第一个标记阶段没有变化,主要是第二个阶段,在这个阶段先将没有死亡的对象移动到另一块空间的连续区域,然后将剩余的所有对象清除。
缺点是需要更新对象引用。常用于老年代GC
(3).复制算法
将内存分为两部分,使用其中一部分储存对象,当这部分内存填满的时候将存活的对象移动到另一块内存中,再清空之前的内存,两块内存区域交换角色,如此循环。
缺点是可能导致内存浪费。常用于新生代,在Eden和两个Survivor区间执行复制算法。
方法区
储存常量池、static静态变量,方法信息(修饰符、方法名称、返回值类型、参数列表等)以及类信息等
虚拟机栈
储存8大基本数据类型,对象引用和实例方法
本地方法栈
储存本地接口库中调用的方法(native关键词)
程序计数器
每个线程启动都会创建一个程序计数器,保存jvm指令,指向下一条指令地址,生命周期与线程相同。
2.类加载器
类加载器的功能是将类文件(.class文件)从硬盘读取到内存中,在堆中创建对象,将静态数据转化成方法区内数据结构
类加载器包括引导类加载器、拓展类加载器、系统类加载器、自定义类加载器
双亲委派机制
类加载器收到类加载请求时,优先交给父类加载器去完成,一直向上委托直到引导类加载器。如父类无法加载,则通知子类加载器往下加载。