java之垃圾回收机制

目录

垃圾回收机制与内存泄漏

GC(garbage collection)的分类

GC判断策略

1.引用计数

2.可达性分析(解决循环依赖问题)

GC收集算法

1.复制算法

2.标记清除算法

3.标记整理算法

JVM所用gc判断策略

分代垃圾收集 

JVM内存(堆里)

1.新生代

2.老生代

新生代与老生代所用gc收集算法

关于新生代与老生代的理解 

三种算法比较

1.复制算法

2.标记清楚算法

3.标记整理算法


垃圾回收机制与内存泄漏

垃圾回收机制:主要是对内存的释放,因为在创建对象时要申请一个空间。

  1. 不再使用的内存空间应回收
  2. java消除了程序员回收无用内存空间的职责,提供了一种系统级别线程跟踪储存空间的分配状况,在JVM的空闲时,检查并释放可被释放的存储空间。
  3. 垃圾收集在java程序运行中自动进行,程序员无法精确控制干预。
  4. GC的自动回收提高了内存空间的使用效率,也提高了编程人员的利用效率,减少了因为没有释放空间而导致的内存泄露。

内存泄漏:内存一直被占着却不能使用。

GC(garbage collection)的分类

  1. 自动GC:一般在JVM内存不足时由JVM系统自动对内存进行垃圾回收
  2. 手动GC:手动的进行内存的分配和释放,如果忘记释放,对应的内存不能被再次使用 
System.gc();  //提醒JVM的垃圾回收执行GC,但是不确定是否马上执行GC

GC判断策略

1.引用计数

每个对象都有一个引用计数属性,新增一个引用时,计数加一,引用释放时,计数减一,引用计数为0时可以回收,此方法简单,无法解决循环依赖问题。

java之垃圾回收机制_第1张图片

  • 绿色云朵是内存中的根对象,表示程序中正在使用的对象
  • 蓝色圆圈是内存中的活动对象,其中的数字表示其引用计数
  • 灰色圆圈是内存中没有活动对象引用的对象,表示非活动对象 

java之垃圾回收机制_第2张图片

  • 红色对象指实际上应用程序使用不到的垃圾对象但由于引用计数的限制,仍然存在内存泄漏 。

2.可达性分析(解决循环依赖问题)

从GC根节点开始向下搜索,搜索走过的路径称为引用链。当一个对象到GC根节点没有任何引用链相连时则证明此对象是不可用的不可达对象。

java之垃圾回收机制_第3张图片

GC收集算法

1.复制算法

将可用的内存按照容量分为大小相等的两块,每次只使用其中的一块,这一块内存用完时就将还存活的对象复制到另一块上面去,然后把已经用过的内存空间一次清理掉(如此循环往复)。 

java之垃圾回收机制_第4张图片

2.标记清除算法

标记阶段:从根节点开始标记所有的可达对象,未被标记的为垃圾对象。

清除阶段:清除所有未被标记的对象

java之垃圾回收机制_第5张图片

3.标记整理算法

标记阶段:从根节点开始标记所有的可达对象,未被标记的为垃圾对象。

整理阶段:将所有存活的对象压缩到内存的一端,之后清理边界外的所有空间。

java之垃圾回收机制_第6张图片

JVM所用gc判断策略

由于引用计数算法不能解决循环依赖问题,JVM并没有使用引用计数算法作为GC中判断对象是否存活的算法,用的是可达性分析。

分代垃圾收集 

 java采用了分代垃圾收集,这种方法会跟java对象生命周期将堆内存划分为不同的区域,在垃圾收集过程中可能会将对象移到不同的区域。

JVM内存(堆里)

1.新生代

  1. 伊甸园区
  2. 存活区

2.老生代

新生代与老生代所用gc收集算法

新生代

  • 复制算法
新生代
区域 启用复制算法次数
伊甸园区 1
存活区 默认15次

老生代

  • 标记清除算法
  • 标记整理算法

关于新生代与老生代的理解 

一般情况下新建的对象均会被分配到伊甸园区(一些大对象特殊处理)这些对象经过第一次gc后,如果仍然存活将会被迁移到存活区,大对象直接进入老生代(大对象指的是需要大量连续内存空间的对象),这样做的目的是避免在伊甸园区和两个存活区之间发生大量的内存拷贝。

三种算法比较

1.复制算法

优点:简单高效
问题:

  • 内存缩小一半,代价太高;
  • 如果对象的存活率很高,就不实用

2.标记清楚算法

优点:速度较快
问题:容易产生内存碎片(主要原因:内存空间不连续)

3.标记整理算法

优点:没有内存碎片
问题:效率不高

你可能感兴趣的