1.  为什么需要垃圾回收?

   因为内存是有限的,在不断的分配内存空间而不回收的话内存迟早都会被消耗完,所以垃圾回收是必须的。

2.  触发GC 的条件:

   1.GC在优先级最低的线程中运行,一般在应用程序空闲即没有应用线程在运行时被调用。

   2.Java堆内存不足时,GC会被调用。

   触发Full GC:调用Sytem.GC();老年代空间不足时;GC担保失败:

2.  GC 工作机制

   1.引用计数法

   给对象中添加一个引用计数器,每当一个地方引用这个对象时,计数器值+1;当引用失效时,计数器值-1。任何时刻计数值为0的对象就是不可能再被使用的。但是这种机制有一种比较致命的缺点:当两个对象互引用时,在遍历时可能会发生这两个对象引数永远不为0,则永远不会被删除。所以该机制在实际的Java中不会使用

   2.可达性分析

   这个方法的机制是通过一系列称为“GC Roots”的对象作为起始点,从这些节点向下搜索,搜索所走过的路径称为引用链,当一个对象到GC Roots没有任何引用链(即GC Roots到对象不可达)时,则证明此对象是不可用的。

   能够作为GC Roots对象的有:虚拟机栈中引用的对象,方法区中的类静态属性引用的对象,方法区中常量引用的对象,本地方法栈中JNI引用的对象。

   

   3.四种引用状态

   强引用:只要强引用还存在,垃圾收集器永远不会回收掉被引用的对象。如:Object obj = new Object()这类的引用

   软引用:描述有些还有用但并非必需的对象。在系统将要发生内存溢出异常之前,将会把这些对象列进回收范围进行二次回收。 如SoftReference表示软引用。

   弱引用:描述非必需对象。被弱引用关联的对象只能生存到下一次垃圾回收之前,垃圾收集器工作之后,无论当前内存是否足够,都会回收掉只被弱引用关联的对象。Java中的类WeakReference表示弱引用。

   虚引用:在这个对象被收集器回收时收到一个系统通知,被虚引用关联的对象,和其生存时间完全没关系。Java中的类PhantomReference表示虚引用

   4.垃圾收集

   标记—清除:程序暂停运行,启动GC,GC从堆或静态存储区开始遍历所有对象,判断对象是否“活”的对象,如果是活不删除,反之删除。判断是否“活”就是判断该对象是否有被其他对象引用,从链上去查找。当是活对象时,会给对象给个标记符号,死对象则不标记,遍历完后,第二次遍历时,只保留标记的对象,把所有没标记的对象都删除。

   停止—复制:程序暂停运行,启动GC,GC从堆或静态存储区开始遍历所有对象,判断对象是否“活”的对象,如果是活不删除,反之删除。判断是否“活”就是判断该对象是否有被其他对象引用,从链上去查找。当是活对象时,GC会从另外堆里开避一个大空间,然后将活对象复制一份到新空间里,在复制时按着紧密排列,同时更新所有引用地址为新的地址,不活对象原封不动。遍历完后,再遍历一次,这次是将不活的对象彻底给删除。

   优点:所有对象能够重新紧密排列,不会出现内存碎片,这对以后创建对象能提供更快的效率。

   缺点:占用的内存空间大,要原对象的2倍空间;这种模式无论如何所有活的对象都要复制一份,假设遍历到最后,对象很稳定,只出现少量垃圾对象或者根本没垃圾对象,这时已经做了复制工作,浪费了资源。

   标记—整理:标记-清除算法一样,不过不是直接对可回收对象进行清理,而是让所有存活对象都向一端移动,然后直接清理掉边界以外的内存。

   分代收集:根据各块的特点采用最适当的收集算法。大批对象死去、少量对象存活的(新生代),使用复制算法,复制成本低;对象存活率高、没有额外空间进行分配担保的(老年代),采用标记-清理算法或者标记-整理算法。

3.  垃圾收集器:

   1.CMS 垃圾收集器:获取最短回收停顿时间为目标的收集器。使用标记 - 清除算法。

    初始标记(标记GCRoots能直接关联到的对象,时间很短)-> 并发标记(进行可达性分析过程,时间很长)-> 重新标记->并发清除(回收内存空间,时间很长)

   2.G1收集器

   并行和并发:使用多个CPU来缩短Stop The World停顿时间,与用户线程并发执行

   分代收集:独立管理整个堆,但是能够采用不同的方式去处理新创建对象和已经存活了一段时间、熬过多次GC的旧对象,以获取更好的收集效果

   空间整合:基于标记 - 整理算法,无内存碎片产生。

最新文章

  1. Debian7下lnmp+gunicorn部署Django运行环境
  2. ecshop /goods.php SQL Injection Vul
  3. iOS学习32之UIKit框架-可视化编程-XIB
  4. GitHub在Visual Studio 2015中获得TFS/VSO同等地位
  5. 解析使用ThinkPHP应该掌握的调试手段
  6. ReentrantLock获取锁方式解读(转)
  7. mac eclipse 安装maven,svn插件
  8. android 获取屏幕尺寸
  9. ubuntu 下面手动安装jdk
  10. <?php function say() { echo 'hello world'; } //在这里调用函数 say(); php 调用方法say()
  11. Fail-Fast机制详解
  12. Protobuf 从入门到实战
  13. OpenCV+VS2013 属性表配置
  14. php的接口,抽象类,trait(转载,合并)
  15. [LeetCode] All Paths From Source to Target 从起点到目标点到所有路径
  16. sublime_text3代码自动补全
  17. model.form使用,配合form的钩子
  18. Jquery Ajax xml版Get请求PHP
  19. 【LeetCode每天一题】Substring with Concatenation of All Words(具备列表中所有单词的字串)
  20. 尚硅谷面试第一季-10SpringMVC的工作流程

热门文章

  1. 洛谷P2515 [HAOI2010]软件安装(tarjan缩点+树形dp)
  2. gcc降版本方法 - [学习]
  3. 51NOD 1134 最长上升子序列
  4. 富文本编辑器vue2-editor实现全屏功能
  5. PostgreSQL - 允许远程访问的设置方法
  6. sql server 获取数据字段(表的字段和类型信息)
  7. 牛客国庆集训派对Day_4~6
  8. 题解报告:poj 1738 An old Stone Game(区间dp)
  9. 生产环境中配置的samba
  10. AJPFX简述Object类