美文网首页
java垃圾收集

java垃圾收集

作者: zhh_happig | 来源:发表于2018-12-29 14:27 被阅读0次

转载、引用请标明出处
https://www.jianshu.com/p/8ec0ee8ca7ee
本文出自zhh_happig的简书博客,谢谢

以下内容,是本人学习的笔记和工作中的总结,仅供大家参考,有误的地方还请指正

一 判定垃圾对象算法

  • 引用计数法
    • 在对象中添加一个计数器,记录着指向对象的引用的个数
    • 当有新的引用指向这个对象的时,计数器+1,当指向对象的引用被置null时,计数器-1
    • 当计数器的值为0,那么这个对象就是垃圾对象,就会被垃圾回收器回收
    • 缺陷:当对象1中有引用指向对象2,对象2中有引用指向对象1,但是再也没有其他外部引用指向对象1和对象2,对象1、对象2是垃圾对象。通过引用计数法,对象1、对象2计数器都为1,不会被垃圾回收器回收。
    • 不推荐使用
  • 可达性分析法
    • 该算法的基本思路就是通过GC Roots对象作为起点,从这些节点开始向下搜索
    • 搜索走过的路径被称为引用链
    • 当一个对象,从GC Roots节点向下搜索,没有任何一条路径能够达到该对象,那么这个对象就是垃圾对象
    • 可以做为GC Roots的对象包括
      • 虚拟机栈中引用指向的对象
      • 方法区中类静态属性所引用的对象
      • 方法区中常量所引用的对象
      • 本地方法栈中引用的对象

二 垃圾回收算法

  • 标记-清除算法
    • 分为标记和清楚2步
    • 标记:就是通过可达性分析法将对象标记为垃圾对象
    • 清除:将垃圾对象回收
    • 缺点:存在效率问题和空间问题
      • 垃圾对象在堆内存中是散乱的,被清除之后,会导致越来越多不连续的空间,当分配大对象时,要寻找一片合适的内存空间,就会变得困难
      • 如果找不到合适的内存空间存放这个大对象,就会触发一次GC,影响性能
  • 复制算法
    • 年轻代的垃圾收集算法,在年轻代对象存活率低,复制算法效率很高
    • 将堆内存分成2部分,只在其中一部分中分配内存
    • 垃圾回收后,把存活的对象复制到另一部分内存连续的空间上
    • 就这样在2个内存中循环复制,这样解决了 标记-清除算法 中的效率问题
    • 缺点:由于只在其中一部分中分配内存,存在内存浪费问题
      • 再将内存细分,即可降低内存浪费,详见Eden、Survivor 0 、Survivor 1、Tenured
  • 标记-整理算法
    • 年老代的垃圾收集算法
    • 在年老代对象存活率高,复制算法效率低,使用标记-整理算法
    • 标记过程仍然与“标记-清除”算法一样,
    • 整理:不是直接清除,而是对内存里面的对象进行重新整理,让所有存活的对象都向一端移动,依次排列,那么端边界另一边的就都是垃圾对象了,直接清理掉
    • 标记-整理算法唯一的缺点就是效率也不高,不仅要标记所有存活对象,还要整理所有存活对象的引用地址。从效率上来说,标记-整理算法要低于复制算法。
  • 分代收集算法
    • 根据不同的内存区选择不同的算法
    • 在年轻代,选择复制算法
    • 在年老代,选择标记-整理算法

三 垃圾回收器

  • Serial
    • 年轻代垃圾收集器,采用复制算法
    • 串行收集器:如果serial要收集垃圾,必须让程序其他线程停掉,收集完毕,程序其他线程继续执行
    • 单线程垃圾收集器:serial单线程收集垃圾
    • 整体效率低
  • Serial Old
    • 它是Serial收集器的年老代版本,与Serial相似,区别是使用“标记-整理”算法
  • Parnew
    • 年轻代垃圾收集器,采用复制算法
    • 串行收集器:如果parnew要收集垃圾,必须让程序其他线程停掉,收集完毕,程序其他线程继续执行
    • 多线程垃圾收集器:parnew多线程收集垃圾
  • Parallel scavenge
    • 与parnew类似,区别是parallel scavenge能控制吞吐量
    • 吞吐量 = 执行用户代码的时间 / (执行用户代码的时间 + 垃圾回收所占用的时间)
      • -xx:MaxGCPauseMillis 垃圾收集器停顿最大时间,就是垃圾收集线程(多线程)收集垃圾的时间,是不是设置越小就越好呢?假设设置100ms,垃圾收集器分配的内存可能是1G,设置为1ms,垃圾收集器分配的内存可能只有10M,因为只有10M这么小的内存才能在1ms内收集完,那么10M内存显然太小了,就会造成垃圾频繁回收。原来100ms回收一次的任务,现在如果1ms回收一次,可能要频繁回收80次,对比之下性能并没有多大提升。所以不是设置的越小越好,应该更具实际情况设置一个合理值。
      • -xx:CGTimeRatio 吞吐量大小
    • 适用注重吞吐量的后端服务
  • Parallel Old
    • 是Parallel Scavenge收集器的年老代版本,与Parallel Scavenge相似,但与Parallel Scavenge不同的是,它使用的是“标记-整理算法”
    • 使用方式:-XX:+UseParallelOldGC,打开该收集器后,将使用Parallel Scavenge(年轻代)+Parallel Old(年老代)的组合进行GC
  • CMS
    • 年老代、永久代垃圾收集器,采用标记-清除算法
    • 并行收集器:垃圾收集线程可以和程序其他线程并发执行
    • 多线程垃圾收集器:CMS多线程收集垃圾
    • 工作过程
      • 初始标记:造成程序其他线程停顿。标记垃圾对象
      • 并发标记:与程序线程并发运行。在运行期间会发生对象的引用变更等等情况,对于这些对象,都是需要进行重新标记的,否则会发生漏标的情况。这个阶段因为是并发的容易导致concurrent mode failure
      • 重新标记:会造成程序其他线程停顿。重新标记的内存范围是整个堆,包含young_gen和old_gen。为什么要扫描新生代呢,因为对于老年代中的对象,如果被新生代中的对象引用,那么就会被视为存活对象,即使新生代的对象已经不可达了。所以需要标记young_gen和old_gen。
      • 并发清理:与程序线程并发运行。并发清理阶段用户线程还在运行着,伴随程序运行自然就还会有新的垃圾不断产生,这一部分垃圾出现在标记过程之后,CMS无法在当次收集中处理掉它们,只好留待下一次GC时再清理掉。这一部分垃圾就称为“浮动垃圾”。
      • 并发重置:与程序线程并发运行。重新设置CMS算法内部的数据结构,准备下一个CMS生命周期的使用
    • 优点
      • 并发收集
      • 低停顿:只有初始标记和重新标记会造成程序其他线程短暂停顿
    • 缺点
      • 占用大量的cpu资源
      • 无法处理浮动垃圾
      • 出现Concurrent Mode Failure
      • CMS收集与应用线程会同时增加对堆内存的占用,也就是说,CMS必须要在老年代堆内存用尽之前完成垃圾回收,否则CMS回收失败,出现Concurrent Mode Failure;
      • 年老代的剩余空间无法满足新对象的空间分配,也会出现这个错误
      • 在出现Concurrent Mode Failure时,将触发担保机制,Serial Old收集器将会以STW的方式进行一次full gc,从而造成较大停顿时间,影响性能
  • G1(Garbage First)
    • JDK7增加,成为HotSpot重点发展的垃圾回收技术,被HotSpot团队寄予取代CMS的使命
    • 将会被安排成为JDK9的默认垃圾收集器
    • 并行收集器:垃圾收集线程可以和程序其他线程并发执行
    • 多线程垃圾收集器:G1多线程收集垃圾
    • 详见G1垃圾收集器

四 垃圾回收器作用内存区域以及他们之间的组合关系

  • 7种不同分代的收集器
    • Serial、ParNew、Parallel Scavenge、Serial Old、Parallel Old、CMS、G1;
  • 垃圾收集器所属区域
    • 年轻代收集器:Serial、ParNew、Parallel Scavenge
    • 年老代收集器:Serial Old、Parallel Old、CMS
    • 整堆收集器:G1
  • 两个收集器间有连线,表明它们可以搭配使用
    • Serial/Serial Old
    • Serial/CMS
    • ParNew/Serial Old
    • ParNew/CMS
    • Parallel Scavenge/Serial Old
    • Parallel Scavenge/Parallel Old
    • G1

以上内容,是本人学习的笔记和工作中的总结,仅供大家参考,有误的地方还请指正

转载、引用请标明出处
https://www.jianshu.com/p/8ec0ee8ca7ee
本文出自zhh_happig的简书博客,谢谢

相关文章

  • 常见Java垃圾收集器

    常见Java垃圾收集器参见:参考 1参考1 Java垃圾收集器

  • Java 内存区域和GC机制

    Java垃圾回收概况 Java GC(Garbage Collection,垃圾收集,垃圾回收)机制,是Java与...

  • Java垃圾收集

    Java垃圾收集算法 Java怎么判断一个对象是否可以回收?当一个对象没有被使用的时候,这个对象就可以回收了,那么...

  • Java垃圾收集

    众说周知,Java与C++同为支持面向对象的语言,但他们对内存的管理方式却有很大的不同。C++开发者往往需要手动调...

  • java垃圾收集

    转载、引用请标明出处https://www.jianshu.com/p/8ec0ee8ca7ee本文出自zhh_h...

  • JVM垃圾回收-STW(Stop-The-World)

    Stop the World机制:在执行垃圾收集算法时,为了保证正确性,Java应用程序的其他所有除了垃圾收集收集...

  • Java 内存区域和GC机制一篇就够了

    Java GC(Garbage Collection,垃圾收集,垃圾回收)机制,是Java与C++/C的主要区别之...

  • Java虚拟机(JVM)调优

    一、Java内存结构 二、堆内存的构成 三、堆内存参数的调整 四、GC如何确定垃圾 五、垃圾收集算法 六、垃圾收集...

  • java和jvm分别查看使用的垃圾收集器

    一、java查看垃圾收集器 使用命令:java -XX:+PrintCommandLineFlags -versi...

  • 黑马手机彩票-高速缓存笔记

    Java GC(Garbage Collection,垃圾收集,垃圾回收)机制,OOM就是内存溢出,即Out Of...

网友评论

      本文标题:java垃圾收集

      本文链接:https://www.haomeiwen.com/subject/bogulqtx.html