1. 新生代区,复制算法的垃圾回收思路:

  • 绝大多数对象的生命周期极短,可能一次新生代垃圾回收过后,99%的对象被垃圾回收了,就1%的对象存活下来,需要长期存活或还没使用完;
  • 新生代内存区域划分为三块:1个 Eden 区2个 Survivor 区
    • Eden 区占 80% 内存空间;
    • 每一块 Survivor 区各占 10% 内存空间
    • 比如说 Eden 区有 800MB 内存,每一块 Survivor 区就 100MB 内存,
  • 平时可以使用的,就是 Eden 区和其中一块 Survivor 区,那么相当于就是有 900MB 的内存是可以使用的;
  • 刚开始对象都是分配在 Eden 区内的;
  • 如果Eden区快满了,此时就会触发 GC,会把 Eden 区中的存活对象都一次性转移到一块空着的 Survivor 区;

image.png

  • Eden 被清空,再次向 Eden 分配新的对象;
    • 此时,Eden 和一块 Survivor 区有对象,其中 Survivor 放的是上一次 GC 后存活的对象;
  • 再次 Eden 区满,那么再次触发 Minor GC,就会把 Eden 区和放着上一次 Minor GC 后存活对象的 Survivor 区内的存活对象,转移到另外一块 Survivor 区去;
  • 然后 GC 清空 Eden 和上一块 Survivor;

image.png
image.png

2. 这样的复制算法垃圾回收和新生代内存分配方式,有哪些好处?

  • 复制算法,将新生代中被标记不可回收的对象,从原有内存区域复制转移到另一块空的区域,可以将这些对象都比较紧凑的排列在内存里,被转移的那块内存区域被清空,多出来一大块连续的可用的内存空间。
    • 避免了因为回收垃圾对象,导致内存碎片太多,很多内存碎片因为空间太小无法存放新对象,造成大量的内存浪费;
  • 新生代内存划分为 80% 的 Eden 区、两个 10% 的 Survivor 区,为了支持复制算法的垃圾回收,使用一块 Survivor 来保存复制转移过来的存活对象,始终保持有 Eden + 一块 Survivor 相当于 90% 的内存可以存放新对象;
    • 新生代的内存利用率很高,只有 10% 的内存是被闲置的,90% 的内存都被用上了;