JVM垃圾回收机制


1.什么是gc ?

gc 垃圾收集回收 是对jvm的内存进行标记和回收,将内存中不再使用的对象进行回收,以便分配给新的对象使用。


2.gc回收哪里的内存?

主要回收的是jvm内存模型中堆区内存,分代收集主要是指堆区的内存(新生代和旧生代),但方法区(持久代)也有少部分比例。(jdk1.6后取消)

既然主要回收的是对内存,那么看一下堆的内存模型:

JVM垃圾回收机制_第1张图片
堆的内存模型
JVM垃圾回收机制_第2张图片
空间分布

注意:

  1.永久代MetaData在jdk1.8之前属于堆,现在属于物理内存,与堆完全隔开了

  2.方法区只是逻辑概念,MetaData永久代和元空间是实实在在存在的,不能混为一体,元空间是方法区的具体实现。


3.gc回收什么样的内存?

a.通过引用计数法,给对象添加一个引用计数器,当有地方引用它时,计数器数值加1,引用失效,数值减1。当一个对象的引用计数器数值为0时,说明它不再被使用,可以回收。这种方法和oc的内存回收是一样的。但弊端是无法很好的处理循环引用的问题。

b.通过根部搜索算法(可达性分析算法), gc roots 向下搜索它们的引用对象,搜索通过的路径成为引用链,当一个对象没有引用链接的时候,说明对象不可达,是需要被回收的。即使循环引用了,只要没有被GC Roots引用了依然会被回收。解决了循环引用的问题。


4.gc操作的过程/何时回收?描述一个具体的过程

1.当试图为java对象在eden区初始化一块内存区域的时候,如果此时eden区足够,则申请结束。

2.若eden区不足,则触发一次gc操作,将存活的对象复制到s0区,并清理eden区。

3.若此时eden区和s0区不足,进行gc操作,将eden+s0区的存活的对象复制到另一个空闲空间s1,然后清理eden+s0区的内存空间。

4.当两个存活区s0和s1来回切换15次,将存活的对象复制到老年代

5.若老年代的空间不足,则major gc 采用标记整理算法清理老年代对象。


5.怎么进行回收?回收算法?—现在JVM使用的GC回收算法—-分代回收算法

a.对新生代(存活时间较短) ——采用复制算法进行回收

具体过程:所谓复制是指 eden区到 survior0 或 survior1区之间copy

把存活对象复制到一个空闲的s区

当eden区满的时候,触发gc,将存活的对象复制到s0区,此时回收eden区的内存

,当eden区再次满了的时候,触发gc,将eden和s0区存活的对象复制到另一个空闲空间s1,此时回收eden和s1区的内存,这样总会有一个空闲的空间s0/s1,作为下一次minor gc存放对象的准备空间。始终会有一个10%空闲的survivor区间,作为下一次Minor GC存放对象的准备空间。

b.对年老代(存活时间较长,而且没有备用的空闲空间)

—-采用标记-整理算法

将存活下来的对象进行标记,向一端移动,保证内存完整性,然后将最后一个活着的对象地址以后的空间全部清理。

—或采用标记-清除算法

从GC ROOTS开始,遍历堆内存区域的所有根对象,对在引用链上的对象都进行标记。存活的对象标记,不存活的进行就进行清理。弊端就是产生大量的碎片空间。


你可能感兴趣的:(JVM垃圾回收机制)