JVM学习总结(三)垃圾回收

什么是垃圾?

答:即Java中程序调用不到的对象。

怎么判断对象是否垃圾,该不该回收?

答:

  1. 引用计数法,对象每次被调用一次,就会+1,当计数到15的时候,该对象就会被扔进老年代;如果没有被调用即-1,当减到0的时候,即为垃圾,会被GC回收。
  2. 根搜查算法,会有GC Roots这么一个东西,如果对象跟GC Root有直接关系或者间接关系,那么就不是垃圾,不会被GC回收,反之。

怎么选择GC Roots?

答:

  1. 本地方法栈中引用的对象。
  2. 方法区中的静态引用对象。
  3. 方法区中的常量引用对象。
  4. Java栈内存中的引用对象,即栈帧中局部表量表中的。

垃圾回收的算法有哪些?

答:标记清除、复制、标记压缩算法

  1. 标记清除算法:对堆内存中的对象进行标记,0表示可达,1表示不可达,清除不可达的对象。缺点是清除完了不可达的对象,会产生内存碎片,这时候,如果还有新的对象并且体积大的放进来,就会出现放不下的问题。
  2. 复制算法:新new的对象会先进入Eden,再放到s1区,垃圾回收的时候会将可达的对象复制到s2区,最后将s1区的对象全部清除。优点,能解决碎片问题,清除速度快。缺点,比较费内存。
  3. 标记压缩算法:GC时候,将可达的对象进行标记,然后将可达的对象整齐地放一边,将不可达的对象放另一边。最后清除不可达的对象。

标记清除、复制为年轻代的算法,标记压缩为老年代的算法,JVM会根据年代来自适应分配算法。

 

小结:

对象新new出来后,会先进入到堆内存的Eden区,再进入S1或者S2区。为什么是或者S2区呢。

严格来说S1区应该叫S(from)区,S2区叫(To)区,并且分配的内存空间是一样大的。

对象是先进入Eden区,如果Eden满了,就会触发GC回收,经历了GC而不被回收的,就会被放入from区。在from区存活达到默认的15次,即会被放入到老年代中。如果from满了,就会经历一次GC复制算法回收。可达的对象就会放到To区。这时候,Eden和from区都被清空了,To区就就会变成刚才的from区,而from区就会变成To区。

无论如何,To区都是空的那片内存来担任。

 

猜你喜欢

转载自blog.csdn.net/weixin_43168480/article/details/107453217
今日推荐