JVM复习(三)几种GC算法

1、引用计数法:没有被Java采用,通过引用计数来标识一个对象是否应该回收,对每一个对象都标记一个数量,一人使用就+1,两人使用就+2....,一旦释放就-1,以此类推。当一个对象引用数量为0,意味着无人使用就可以进行空间释放了。

引用计数法问题:伴随着加法和减法,影响性能;很难处理循环引用问题。

2、几大概念:

  1. :栈中引用的对象;方法区中静态成员或者常量引用的对象;JNI方法栈中引用对象
  2. 可达对象:可触及的,从根节点可以触及到这个对象
  3. 可复活对象:一旦所有引用被释放,就是可复活,在finalize()复活
  4. 不可触及:在finalize()后,可能进入不可复活;不可触及对象不可复活;可以回收

(尽量避免使用finalize,操作不慎容易引发错误,何时调用不确定,使用try-catch-finally替代)

3、标记-清理:现代垃圾回收算法的思想基础,分为两个阶,标记阶段:首先通过根节点,标记所有从根节点开始的可达对象,未被标识的即为未被引用的垃圾对象;清理阶段:清除所有未被标记的对象

4、标记-压缩:优化了标记-清理,适合存活对象较多的场合,如老年代(存活周期较长)。标记阶段:首先通过根节点,标记所有从根节点开始的可达对象,未被标识的即为未被引用的垃圾对象;清理阶段将所有存活对象压缩到内存的另一端,之后,清理边界外所有空间。

5、复制算法:不适合存活对象多的场合,适合少量对象存活,适合新生代(存活周期较短)。将原有内存空间分为两块,每次只使用其中一块,在垃圾回收时,将正在使用的内存中存活的对象复制到未使用的内存块中;之后,清除正在使用的内存块中的所有对象,交换两个内存的角色,完成垃圾回收。

复制算法问题:空间浪费

6、STW(Stop-The-World)现象:Java中一种全局停顿现象。所有Java代码停止,native代码可执行,但不可和JVM交互,多半由于GC引起。

  1. 例如:聚会打扫房间时,聚会没停止,会有新的垃圾产生,永远打扫不干净,让大家停止活动,才能将房间打扫干净。
  2. 危害:长时间服务停止,无响应;遇到HA(高可用)系统,可能引起主从切换(可理解为mysql的主从复制,Redis的哨兵机制等等之类)
  3. 尽可能减少一次STW停顿时间方法:垃圾算法选择;一程序使用堆设置;无用对象尽早释放。
  • 多核cpu,可以采用并行和并发收集器,如果是响应时间优化的系统应用 ,则jdk6版本一般选择的垃圾回收算法是:XX:+UseConcMarkSweepGC,即cms收集器,这个收集器垃圾回收时间短,但是垃圾回收总时间变长,使的降低吞吐量,算法使用的是标记-清除,并发收集器不对内存空间进行压缩,整理,所以运行一段时间以后会产生"碎片",使得运行效率降低.CMSFullGCsBeforeCompaction此值设置运行多少次GC以后对内存空间进行压缩,整理
  • 根据程序运行情况,通过Jvm垃圾回收分析,设置一个比较合适的堆大小,不能一意味的将堆设置过大,导致
    程序回收很大一块空间,所以会导致stw时间较长
  • 使用的对象,如果没有用,尽早设置null,尽量在年轻代将对象进行回收掉,可以减少full gc停顿时长

猜你喜欢

转载自blog.csdn.net/qq_37575994/article/details/102646283