⭐️⭐️6.类加载
类加载器
JVM只会运行二进制文件,类加载器的作用就是将字节码加载到JVM中,从而让程序启动
1.启动类加载器 ----JAVA_HOME/jre/libC++编写加载的是JAVA_HOME/jre/lib
2.拓展类加载器 ----JAVA_HOME/jre/lib/ext
3.应用类加载器 ----ClassPath自己编写的java程序
4.自定义加载器 ----实现自定义加载
⭐⭐7.双亲委派机制
在加载类的时候,先委托上一级的加载器进行加载,如果上一级加载器也有上级,则会继续向上委托。如果上级加载器无法加载,子类加载器就会尝试加载该类
这样的作用:
1.通过双亲委派机制可以避免莫一个类被重复加载,当父类已经加载后则无需重复加载,保证唯一性
2.保证了类库API不会被修改
3.简化了加载流程:通过委派,大部分类能够被正确的类加载器加载,减少了每个加载器需要处理的类的数量,简化了类的加载过程,提高了加载效率
⭐️8.类装载的执行过程
加载:通过类的全名 ,获取类的二进制数据流;解析类的二进制数据流为方法区的数据结构(Java类模型);创建Java.lang.Class对象,作为方法区这个类的各种数据的访问入口。
连接:验证,准备,解析
- 验证:验证类是否符合JVM规范,安全性检查(文件格式,元数据,字节码,符号引用)
- 准备:为类变量分配内存并设置类变量初始值
- 解析:把类中的符号引用转换为直接引用。
符号引用:方法中调用其他方法,这个方法名就可以理解为符号引用;
直接引用就是指针直接指向方法;
初始化:对类的静态变量,静态代码执行初始化操作
如果初始化一个类的时候,父类尚未初始化,则会优先初始化父类;
如果同时包含多个静态代码块和静态变量,则按照自上向下的顺序依次执行;
使用:用类或者创建对象
卸载:1.该类所有的实例都已经被回收,也就是Java堆中不存在该类的任何实例。2.加载该类的ClassLoader已经被回收。3.类对应的Java.lang.Class对象没有任何地方被引用,无法在任何地方通过反射访问该类的方法。
⭐️9.判断垃圾的方法
垃圾回收指的是堆中的对象。
垃圾指的是如果一个或多个对象没有任何的引用指向它了,那么这个对象现在就是垃圾。
引用计数法:
为每个对象分配一个引用计数器,每当有一个地方引用它时,计数器加1;当引用失效时,计数
器减1。当计数器为0时,表示对象不再被任何变量引用,可以被回收。
可达性分析算法:
一组称为GC Roots(垃圾收集根)的对象出发,向下追溯它们引用的对象,以及这些对象引用的其他对象,以此类推。如果一个对象到GC Roots没有任何引用链相连(即从GC Roots到这个对象不可达),那么这个对象就被认为是不可达的,可以被回收。
GC Roots对象包括:虚拟机栈(栈帧中的本地变量表)中引用的对象、方法区中类静态属性引用的对象、本地方法栈中JNl(Java NativeInterface)引用的对象、活跃线程的引l用等。
⭐️⭐️10.垃圾回收算法
垃圾回收机制的主要目标是自动检测和回收不再使用的对象,从而释放它们所占用的内存空间。这样可以避免内存泄漏(一些对象被分配了内存却无法被释放,导致内存资源的浪费)。同时,垃圾回收机制还可以防止内存溢出(即程序需要的内存超过了可用内存的情况)
标记清除算法:
标记清除算法,是将垃圾回收分为俩个阶段:标记和清除
1.根据可达性分析算法得出的垃圾进行标记
2.对这些标记为可回收的内容进行垃圾回收
优点:标记和清除速度较快
缺点:碎片化较为严重,内存不连贯
标记整理算法:
标记整理算法,是将垃圾回收分为俩个阶段:标记和整理在删除。标记压缩算法是在标记清除算法的基础之上,做了优化改进的算法。和标记清除算法一样,也是从根节点开始,对对象的引用进行标记,在清理阶段,并不是简单的直接清理可回收对象,而是将存活对象都向内存另一端移动,然后清理边界以外的垃圾,从而解决了碎片化的问题
1.标记垃圾
2.需要清除的想右边走,不需要清除的向左边走
3.清除边界以外的垃圾
优缺点同标记清除算法,解决了标记清除算法的碎片化的问题,同时,标记压缩算法多了一步,对象移动内存位置
的步骤,其效率也有有一定的影响。
与复制算法对比:复制算法标记完就复制,但标记整理算法得等把所有存活对象都标记完毕,再进行整理
复制算法:
复制算法,将原有的内存空间一分为二,每次只用其中的一块,在垃圾回收时,将正在使用的对象复制到另一个内存空间中,然后将该内存空间清空,交换两个内存的角色,完成垃圾的回收
优点:在垃圾多的情况,效率较高;清理之后内存没有碎片。
缺点:分配了两块内存空间,同一个时刻只能使用一半,内存使用率较低
分代回收算法
分代收集是将内存划分成了新生代和老年代。分配的依据是对象的生存周期,或者说经历过的 GC 次数。对象创建时,一般在新生代申请内存,当经历一次 GC 之后如果对还存活,那么对象的年龄 +1。当年龄超过一定值(默认是 15,可以通过参数 -XX:MaxTenuringThreshold 来设定)后,如果对象还存活,那么该对象会进入老年代。
⭐️11.垃圾回收器
串行垃圾回收器
Serial:作用于新生代,采用复制算法
Serial Old:作用与老年代,采用标记-整理算法
垃圾回收时,只有一个线程在工作,并且java应用所有线程都要暂停,等待垃圾回收完成
并行垃圾回收器
Parallel New:作用于新生代,采用复制算法
parallel Old:作用与老年代,采用标记-整理算法
垃圾回收时,只有多个线程在工作,并且java应用所有线程都要暂停,等待垃圾回收完成
CMS(并发)垃圾回收器
CMS全称 Concurrent Mark Sweep,是一款并发的、使用标记-清除算法的垃圾回收器,该回收器是针对老年代垃圾回收的,是一款以获取最短回收停顿时间为目标的收集器,停顿时间短,用户体验就好。其最大特点是在进行垃圾回收时,应用仍然能正常运行。
G1垃圾回收器
(Garbage First)收集器 (标记-整理算法):Java堆并行收集器,G1收集器是JDK1.7提供的一个新收集器,G1收集器基于"标记-整理"算法实现,也就是说不会产生内存碎片。此外,G1收集器不同于之前的收集器的一个重要特点是:G1回收的范围是整个Java堆(包括新生代,老年代),而前六种收集器回收的范围仅限于新生代或老年代
1.应用与新生代和老年代,JDK之后默认使用
2.划分成多个区域,每个区域都可以充当Eden,survivor,old,humongous,其中humongous是为大对象准备。
3.采用复制算法,标记-整理算法,分代回收算法
4.分为三个阶段:新生代回收,并发标记,混合收集
5.如果并发失败(回收的速度赶不上创建对象的速度),会触发Full GC
Young Collection(年轻代垃圾回收)
1.初始时,所有区域都处于空闲状态
2.创建了一些对象,挑出一些空闲区域作为Eden(伊甸园区)区存储这些对象
3.当Eden(伊甸园区)需要垃圾回收时,挑出一个空闲区域作为S(幸存区)区,用复制算法复制存活对象,这时候处于STW(线程暂停)
4.随着数据流逝,Eden(伊甸园区)内存又有不足
5.将Eden(伊甸园区)以及之前幸存区中的存活对象,采用复制算法,复制到新的S(幸存区),其中较老的对象晋身老年代
Young Collection + Councurrent Mark(年轻代垃圾回收 + 并发标记)
当老年代占用超过阈值(45%)后,触发并发标记,这时无需暂停用户线程
- 并发标记之后,会有重新标记阶段解决漏标问题,此时需要暂停用户线程。
- 这些都完成后就知道了老年代有哪些存活对象,随后进入混合收集阶段。此时不会对所有老年代区域进行回收,而是根据暂停时间目标优先回收价值高(存活对象少)的区域(这也是 Gabage First 名称的由来)
Mixed Collection (混合垃圾回收)
复制完成,内存得到释放。进入下一轮的新生代回收、并发标记、混合收集