1. 什么是垃圾
没有任何引用指向的对象就是垃圾。
2. 怎么找到垃圾
1)引用计数
缺点:循环引用不能解决
2)根可达算法
3. 垃圾回收算法
1)标记清除
优点:①算法简单,②适用于存活对象比较多的情况(老年代)
缺点:①需要扫描两遍,效率低;②容易产生碎片
2)复制
优点:①适用于存活对象较少的情况(年轻代);②只扫描一次,效率高;③没有碎片
缺点:①空间浪费;②移动复制对象,需要调整对象引用
3)标记整理
优点:①不会产生碎片;②不会产生内存减半(相对于复制算法)
缺点:①扫描两次;②需要移动对象,效率偏低
4. 堆内存逻辑分区
G1逻辑分代,物理不分代
目前最新的垃圾回收器,像ZGC,是不分代的。
其他老的垃圾回收器,不仅逻辑分代,也物理分代。
1)一个对象从出生到消亡
一个对象先尝试往栈上分配,要是分配不下,就往eden区分配
垃圾回收一次,往survior区分配
在两个survivor之间回收超过15次,就会往老年代分配
5. 对象分配
1)栈上分配(什么样的对象会分配在栈上)
- 线程私有小对象
- 无逃逸(只在某段代码中使用,局部变量)
- 支持标量替换
无需调整
2)线程本地分配(TLAB)
每个线程在eden区默认有一块1%的区域,对象分配时,优先往这个地方进行分配
- 占用eden,默认1%
- 多线程的时候不用竞争eden就可以申请空间,提高效率
- 小对象
无需调整
3)对象什么时候进入老年代
GC的age是4位,能最大存储的数是1111,15
4)对象分配过程
6. java参数
1)java -X命令
可以查看所有的-X开头的参数(非标准参数)
2) java -XX:+PrintFlagsFinal -version
可以查看所有的java参数
3) java -XX:+PrintFlagsFinal -version | grep Tenure
查找Tenure开头的参数
7. 常见的垃圾回收器
1)Serial
单线程、年轻代,STW
2)Serial Old
单线程,老年代,与Serial配合使用,使用标记整理算法,STW
3)Parallel Scavenge
年轻代,多线程垃圾回收,STW
4)Parallel Old
老年代,多线程,与 Parallel Scavenge搭配使用
5)ParNew
年轻代,在parallel scavenge的基础上做了强化
6) CMS
老年代,标记清理算法
cms的jdk1.4版本后期引入,cms是里程碑式的GC,它开启了并发回收的过程,但是CMS毛病较多,因此,目前没有任何一个jdk版本默认的垃圾回收器是CMS
设计目的:内存越来越大,STW的时间越来越长,需要CMS来减少STW的时间
并发清理过程中,产生的垃圾,叫做浮动垃圾 ,需要下一次清理的时候清理掉
CMS的问题:
1. 标记清理算法,会导致内存碎片化
2. 产生浮动垃圾
3. CMS如果不能正常运行,会用Serial Old替代
8. 并发标记的算法
CMS使用的是三色标记+ Incremental Update
G1使用的是三色标记+ SATB
9.methodArea方法区
存放的是代码的源信息、代码的编译信息
1.7之前是永久代
1.8开始是metaspace(元数据)
区别:
1. 永久代存放的是元数据,class,代码编译后的信息
2. 永久代必须指定大小限制,元数据可以设置,也可以不设置,无上限(受限于物理内存)
3. 字符串常量:1.7永久代 ,1.8堆
4. methodArea 逻辑概念 永久代,元数据
新生代和老年代叫堆