GCRoot:
栈,方法区,本地方法栈是不会被清理的,还有间接引用的对象也不会被清理

清理算法:

  1. 标记-清理 缺点:会有内存碎片
  2. 标记-整理 缺点:因为所有内存都要前移,代价太大
  3. 复制算法 缺点:需要2倍内存

GC中实际用的算法:
image.png

将内存分为2个区域,年轻带和老年带
年轻代:又分为E区(伊甸园区)和survive区(s0,s1)它们的比例是8:1:1.
new的对象都会存在于E区,不要被清理的对象会打标记,用复制算法,复制到S0区。然后清理掉E区和S1区,如下图所示,一直交替
image.png
当young GC次数达到15次就不会复制了,而是直接到old区中。old也会存放一些大对象。当old区内存也快满了,那么old区和young区也会开始gc操作。这个操作叫full GC,java程序会直接暂停报StackOverflowError。然后全力进行垃圾回收,清理的算法用的是 标记清理或标记整理的办法
image.png
像young取常用的gc清理器就是ParNew,Old用的是CMS.像新的JDK版本已经没有使用前面的二种垃圾清理方式了而是用的G1清理器

面试官问了一个这样的问题,YoungGC触发时会发生什么,我回答E区和S0区存活的对象会复制到S1区,然后清理E区和S0区,下一次GC时E区和S1区存活对象会复制到S0区,以此交替(不考虑对象进入老年代)。面试官继续问:E区和S0区的所有存活对象都可以复制到S1区吗?S1区能放下这么多对象吗?E区和S0区清理是整个删除吗?
1.s1是有可能放不下所有的cun活对象的,这时候会直接存放在old区
2.然后最后是整个清除吗?这个我一直认为是,但是非要钻牛角的话,fullgc后仍没有空间的情况下,就是另一种情况了,这时候甚至会在old区进行new对象。

JAVA逃逸分析

0a75c92537f5041f6b92e345f3f304a.png
-XX:DoEscapeAnalysis 关闭GC
-Xmx10m -Xms10m -XX:+PrintGC -XX:-DoEscapeAnalysis
逃逸分析是分析了对象只在当前函数范围内使用,因而改为在栈上申请空间。而栈是函数运行完,立刻清理的,所以不需要等到gc了,大大缓解了gc的压力。

垃圾收集器 | g1收集器

image.png

image.png