学习马士兵老师的课程,根据笔记自己得出以下自己的理解,继续学习后续课程后,再来添加笔记。
什么是垃圾?如何定义垃圾?
栈中 ,每个方法一个栈帧,每个方法结束后,自动释放。这时,堆中有堆空间没有被引用,但是每个堆空间都不允许被访问,这些堆空间就是垃圾。
c和c++都是手工释放垃圾。
这就存在几个问题:
1.如果堆中的空间一直没有释放,此时这个空间一直被占用状态,这就会导致内存泄漏,泄漏得多了,就导致了内存溢出。
2.如果释放了多次,就可能会导致误删。例如:程序1第一次释放空间后,程序2又访问了该空间,这时因为代码问题,程序1又释放了一次,把程序2引用的空间删除,程序2就会出现异常。
3.但是运行效率高。
推出Java后,就加入了GC这个概念
GC(Garbage collector) 垃圾回收器
Java垃圾回收器,采用了GC Root (根可达)
什么是根可达?
每个栈中的栈帧都算一个ROOT,顺着线向下引用能引用到都不是垃圾,没有引用到的都是垃圾。
那要怎么释放呢?有三种方法:
1.标记回收
通过根可达,没有引用到的堆空间,都加上标记,告诉大家,这个空间可以被方法啦。
这就有一个问题
如果很多空间都被标记了,那堆中就有很多的小洞,空间不连贯,碎片化严重。
2.Copying
将空间一分为二,当GC入场后,就把所有有被引用的空间全部都Copy到另一半空间,然后把之前的空间内全部删除。
但是这会导致内存浪费
3.标记压缩
当标记回收后,碎片化十分严重时,就会使用标记压缩,将碎片化空间全部压缩整合。
常用的垃圾回收器
分代模型:
常用组合
1.serial+serial old
2.parallel scavenge + parallel old
3.CMS + parnew
4.G1
5.ZGC
6.shenandoah
7.epsilon
1、2以及parnew都是
STW(stop-the-world)
GC入场后,让所有线程都停止!等垃圾回收后,再继续运行。
CMS 、G1、ZGC、shenandoah
统称为ConcurrentGC
并发完成垃圾回收
如何查看GC版本
在cmd中输入命令
java -XX:+PrintCommandLineFlags -version
最后的-UseParallelGC
就体现我在使用parallel scavenge + parallel old