垃圾回收的过程
1 垃圾回收
2 GCRoot
2-1 JVM是如何判断垃圾对象的。
简单地来说,就是从gc roots的根出发(即局部变 量表中的引用对象),
一路沿着引用关系找,凡是能够被找到的对象都是非垃圾对象,
并且会被移动到下一个它应该去的区域 中。
剩下的对象,会在区域清空时,一同被清理掉而无须关心。
2-2 哪些可以作为GC-ROOT呢
-
常量
-
类中的静态变量
-
栈中的引用
3 垃圾回收算法
3-1 标记清除
标记清除后并没有重新整理可用的内存空间,就会产生一个问题:
如果内存中可被回收的小对象对,就会产生内存碎片,
那么大对象就无法获得可用连续的空间
3-2 复制算法
将内存分为大小相等的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进程,
回收整个内存模型当中的内存资源,从而造成用户响应超时或者是系统无响应,
这 对于并发程序比较高的系统(比如秒杀活动)影响程度是极其之大的。