垃圾回收的过程

1 垃圾回收

2 GCRoot

2-1 JVM是如何判断垃圾对象的。

简单地来说,就是从gc roots的根出发(即局部变 量表中的引用对象),

一路沿着引用关系找,凡是能够被找到的对象都是非垃圾对象,

并且会被移动到下一个它应该去的区域 中。

剩下的对象,会在区域清空时,一同被清理掉而无须关心。

2-2 哪些可以作为GC-ROOT呢

  • 常量

  • 类中的静态变量

  • 栈中的引用

3 垃圾回收算法

3-1 标记清除

image

标记清除后并没有重新整理可用的内存空间,就会产生一个问题:

如果内存中可被回收的小对象对,就会产生内存碎片,

那么大对象就无法获得可用连续的空间

3-2 复制算法

image

将内存分为大小相等的2份,

当内存1对象存储满后,会对内存1进行标记,

将标记后存活的对象复制到内存2,然后直接清空内存1

这个也会产生一个问题:内存利用率太低,每次只使用一半的内存。

3-3 标记整理

3-4 分代收集

jvm将堆划分为新生代和老年代

新声代

新生代主要是新生成的对象,特点是:

对象多,生命周期短,在每次垃圾回收都会有大量对象被回收

新生代采用的是复制算法,新生代主要分为Eden,From,To三个区,一共10份,

占比为8:1:1

进行垃圾回收时候,会将eden和from中存活的对象复制到to

老年代

老年代主要存大对象和生命周期长的对象

老年代采用标记清除算法,因为是大对象嘛,也很难产生碎片的问题。


1-我们new的对象一开始在Eden

当Eden满了后,会触发一次垃圾回收。

存活的对象被分配到From,然后清空Eden,存活的对象年龄加1

2-继续new对象,放在Eden,

当Eden满了以后,存活的对象移动到to 区域,然后清除Eden和from

内存中的对象主要被分配到Eden From两区域,在新生代的Eden From区域内存空间不足会触发一次垃圾回收,该过程称为Minor GC,然后Eden From存活的对象会被复制到to区域,

Eden From会被清理。

3-如果此时在to区无法找到连续空间存储某个对象,那么这个对象直接存储到老年代。

如果servivor区的对象经过一次垃圾回收仍然存活,那么其年龄+1,对象的年龄达到15,被移到老年代。

126-垃圾回收过程

程序一开始,所有的实例对象都会生成在Eden区中,
当Eden区满了的时候,这时就会触发minor gc,jvm使用gc roots的
查找方式将非垃圾对象移动(复制算法)到S0区域中去,
并且将Eden区中的其他对象视为垃圾对象,清空Eden区。

当实例对象再次充满Eden区时,又会触发minor gc;
但是这次是将Eden区和S0区中的所有非垃圾对象移动到S1中,并清空Eden 区和S0区;

同样下次minor gc时,就是将Eden区和S1区中的非垃圾对象转移到S0中

当达到 15(默认情况)时,这个对象就会被放到老年代中去,成为长期存在的对象

老年代空间也有限啊,满了,在full gc时,jvm会先触发STW(Stop-The- World),也就是暂停其他所有的java进程,
回收整个内存模型当中的内存资源,从而造成用户响应超时或者是系统无响应,
这 对于并发程序比较高的系统(比如秒杀活动)影响程度是极其之大的。


posted @ 2021-12-13 12:45  姚狗蛋  阅读(157)  评论(0编辑  收藏  举报