1> Class 类加载
主动加载的几种情况:
-
Student student = new Student(); 最常用的方式
-
反射或者clone的方式
-
初始化子类的时候,父类会被优先初始化。
-
调用一个类的静态方法。
类的加载分为5步:
-
加载 ClassLoader
1> 全路径名称,获得类的二进制数据流。
2> 解析类的数据流,转化为方法区(永久代、元空间)内部数据结构。
3> 创建Class类的实例。
-
验证
4步的:格式、语义、字节码、符号引用
符号引用:
直接引用:
-
准备
虚拟机会为这个类分配相应的内存空间。
-
解析
符号引用转化为直接引用了。
-
初始化
把类加载到系统中,这个时候,类才会开始执行java字节码。
2> 栈针操作
1>java栈线程私有的。
2>每次函数的调用都是通过栈传递的。
3>先进后出。每次方法调用的时候——>入栈; 每次方法执行完毕的时候——>出栈。
4>局部变量表、操作数栈、帧数据区。
3> 垃圾回收算法
3.1> 可触及性——判断垃圾
-
可触及
从根节点开始,可以到达某个对象。
-
可复活
finalize()
-
不可触及
finalize()只会执行一次,错过了这个复活机会,那么就是不可触及的状态。
3.2> 引用级别(常见面试题)
一共四个级别:
-
强引用
Student student = new Student();
-
软引用(java.lang.ref.SoftReferenct)
堆空间不足的,才会被回收。
-
弱引用(java.lang.ref.WeakReferenct)
当GC的时候,只要发现存在弱引用,无论系统堆空间是否不足,都会被回收。
-
虚引用
跟没有引用是一样的。
讲完了触及性和引用级别,我们来看一道面试题LocalValueGC.java
槽位复用
3.3> 垃圾回收算法
6大垃圾回收算法,分别是:
1> 计数法
- 它是最古老的垃圾收集方法。
- 有问题的
- 循环引用。
- 性能问题。
2> 标记清除法
现代垃圾回收算法的思想基础
-
优点
- 实现简单。
- 与保守式GC算法相兼容的。(保守式GC算法中,对象是不能被移动的)
-
缺点
- 内存的空间碎片化。
- 分块是不连续的,遍历空闲的链表。如果分配大对象的时候,最差的情况,可能是在最后才找到合适的内存空间进行分配。
-
保守式GC
不能识别的指针和非指针的GC。
优点:
1> 语言处理程序步依赖于GC的。简单。
缺点:
1> 识别指针和非指针是需要付出成本的。
2> 错误识别指针会压迫堆。
3> 能够使用的GC算法有限。
3> 复制算法
为了解决效率问题和空间碎片问题,而产生的。
- 优点
- 执行效率高
- 没有内存碎片
- 缺点
- 内存空间只能使用1/2
复制算法在JVM堆中的应用
新生代:Eden——S0——S1 8:1:1 可以使用的空间Eden+S0= 8+1=90% 可以使用的空间 S1=10% 不可以使用的空间
-XX:SurvivorRatio
进入老年代:
- 设置BIgObject -XX:PretenureSizeThreshold
- 设置OldObject -XX:MaxTenuringThreshold
4> 标记压缩算法
- 老年代的算法。
- 在标记清除算法的基础上进行的优化。性价比很高。
- 不会产生内存碎片
5> 分代算法
新生代——>复制算法
老年代——>标记清除、标记整。
6> 分区算法
将整个堆空间,划分成多个小的空间,然后针对垃圾比例较高的空间,执行GC回收。这样,可以提升一次GC的耗时。
4> 垃圾收集器
1> 串行回收器
-
Serial回收器,单线程,独占式。它是最古老的回收器。
-
在JDK1.3之前,它是新生代收集器唯一的选择。
-
client模式下,是默认的新生代收集器。
-
单线程的。特点:单核/内核少的计算机来说,它的性能表现很好。简单高效。
-
-XX:+UseSerialGC指定新生代&老年代都是用串行回收器。
-
新生代——>复制算法。 老年代——>标记压缩算法。
2> 并行回收器
-
独占式的。与串行回收器唯一不同的就是,多线程并发的。
-
如果单核/内核少的计算机来说,它的性能不如串行回收器。
-
-XX:ParallelGCThreads=8(默认值),当我们CPU的数量少于8的时候,并行8。 如果大于8,并行线程数量3+(5*cpu_nums/8)
-
CMS(关心系统的停顿时间)
1>初始标记 STW
标记根对象。
2>并发标记
标记所有对象。
3>预清理
清理前的准备和控制停顿时间,可以被关闭的。
4>重新标记 STW
预测下一次新生代发生GC的时间,然后取中间时刻。
目的:尽量避免新生代GC和重新标记重叠执行。从而减少一次停顿时间。
5> 并发清理
真正的执行类清理操作
6>并发重置
收尾的工作。
缺点:内存碎片。
-XX:+UserCMSCompactAtFullCollection : 指定GC后,进行一次碎片整理。
-XX:+CMSFullGCsBeforeCompaction:指定执行多少次GC后,进行一次碎片整理。
3> G1回收器
3.1>新生代GC
* 主要的工作就是回收Eden取和Servivor区。
3.2>并发标记周期
-
初始标记 STW
标记从根节点直接可到达的对象。
-
根区域扫描
扫描survivor区可以直达老年代的对象。
-
并发标记
再次扫描堆的存活对象。再次进行了确认标记。
-
重新标记 STW
由于并发标记阶段,应用程序也是并发的。那么这个阶段,会对标记的结果进行最后的修正。
-
独占清理 STW
计算各个区域的存活对象和GC回收比例。然后进行一个比例的排序。供混合收集使用。
-
并发清理
取识别并清理哪些完全空闲的区域。
3.3>混合收集
- 回收垃圾比例较高的区域。(减少每次GC时间)
- 新生代和老年代GC都会同时执行。那么被清理区域中的存活对象就会被移动到其他区域。(减少内存碎片)