转载自链接

垃圾收集器一般必须完成两件事:检测出垃圾、回收垃圾。怎么检测出垃圾?一般有以下几种方法:

1.引用计数法:

给一个对象添加引用计数器,每当有一个地方引用它,计数器就加一,引用失效就减一。好了,问题来了,如果我有两个对象互相引用,除此之外没有其他任何对象引用他们,实际上这两个对象已经无法访问,即我们说的垃圾对象。但他们互相引用,计数不为0,所以无法回收。这就是引用计数法的缺陷。

2.可达性分析算法(也叫根搜索算法):

以根集对象为起始点进行搜索,如果有对象不可达的话,即为垃圾对象。这里的根集一般包括:java栈中的引用对象、本地方法栈中JNI的引用对象、方法区中运行常量池中的引用对象、方法区中静态属性引用的对象、运行中的线程、由引导类加载器加载的对象、GC控制的对象。总之,JVM在做垃圾回收的时候,会检查堆中的所有对象是否被这些根集中的对象所引用,不能够被引用的对象就会被垃圾回收器回收。

回收垃圾的算法有:

1.标记--清除(mark--sweep):

算法和名字一样分为两个阶段:标记和清除。标记所有需要回收的对象,之后统一回收。这是最基础的算法,后续的回收算法都是基于这个算法扩展的。

不足:效率低,标记清除之后会产生大量碎片。效果图如下:

灰色的表示要被回收。

2.复制(copying):

此算法把内存空间划分为两个相等的区域,每次只使用其中的一个区域。垃圾回收时,遍历当前使用区域的所有对象,将正在使用中的对象复制到另一个区域。此算法每次只处理使用中的对象,因此复制成本比较小,同时复制过去之后还能进行相应的内存整理,所以不会出现碎片问题。

不足:缺点也很明显就是需要两倍的内存空间。以空间换取时间。效果图如下:

灰色的表示要被回收。

3.标记--整理(mark--compact):

此算法结合了标记--清除和复制的有点,也是分两个阶段,第一阶段是从根节点遍历所有对象标记所有能被引用的对象,第二阶段遍历整个堆中的对象,清除所有未被标记的对象,并把所有存活对象“压缩”到堆的其中一块,按顺序排放。此算法避免了“标记--清除”的碎片问题,也没有“复制”的空间问题。效果图如下:

4.分代收集算法:

这是当前商业虚拟机常用的一个垃圾收集算法。分代的垃圾收集策略是基于这样的一个事实:不同对象的生命周期是不一样的,因此对于不同生命周期的对象可以采用不同的收集算法,以便提高效率。

为什么要运用分代垃圾回收策略?在java程序运行的过程中会产生大量的对象,因为每个对象所承担的职责与功能不同,所以他们的生命周期也不相同,有的对象生命周期比较长,例如:HTTP请求中的session对象,线程对象,socket连接等,有的对象生命周期比较短,例如:比如String对象,有的对象在使用一次后就可以回收。试想,在不进行对象存活时间区分的情况下,每次垃圾回收都是对整个堆空间进行回收,那么消耗的时间相对会很长,而且对于存活时间较长的对象进行的扫描工作等都是徒劳。因此就需要引入分治的思想,所谓分治的思想就是因地制宜,将对象进行代的划分,把不同生命周期的对象放在不同的代上使用不同的垃圾回收方式。

如何划分?将对象按其生命周期的不同划分成:年轻代(Young Generation)、年老代(Old Generation)、持久代(Permanent Generation)。其中持久代主要存放的是类信息,所以与java对象的回收关系不大,与回收息息相关的是年轻代和年老代。这里有个比喻很形象

“假设你是一个普通的 Java 对象,你出生在 Eden 区,在 Eden 区有许多和你差不多的小兄弟、小姐妹,可以把 Eden 区当成幼儿园,在这个幼儿园里大家玩了很长时间。Eden 区不能无休止地放你们在里面,所以当年纪稍大,你就要被送到学校去上学,这里假设从小学到高中都称为 Survivor 区。开始的时候你在 Survivor 区里面划分出来的的“From”区,读到高年级了,就进了 Survivor 区的“To”区,中间由于学习成绩不稳定,还经常来回折腾。直到你 18 岁的时候,高中毕业了,该去社会上闯闯了。于是你就去了年老代,年老代里面人也很多。在年老代里,你生活了 20 年 (每次 GC 加一岁),最后寿终正寝,被 GC 回收。有一点没有提,你在年老代遇到了一个同学,他的名字叫爱德华 (慕光之城里的帅哥吸血鬼),他以及他的家族永远不会死,那么他们就生活在永生代。”

年轻代:是所有新对象产生的地方。年轻代被分为3个部分——Enden区和两个Survivor区(From和to)当Eden区被对象填满时,就会执行Minor GC。并把所有存活下来的对象转移到其中一个survivor区(假设为from区)。Minor GC同样会检查存活下来的对象,并把它们转移到另一个survivor区(假设为to区)。这样在一段时间内,总会有一个空的survivor区。经过多次GC周期后,仍然存活下来的对象会被转移到年老代内存空间。通常这是在年轻代有资格提升到年老代前通过设定年龄阈值来完成的。需要注意,Survivor的两个区是对称的,没先后关系,from和to是相对的。

年老代:在年轻代中经历了N次回收后仍然没有被清除的对象,就会被放到年老代中,可以说他们都是久经沙场而不亡的一代,都是生命周期较长的对象。对于年老代和永久代,就不能再采用像年轻代中那样搬移腾挪的回收算法,因为那些对于这些回收战场上的老兵来说是小儿科。通常会在老年代内存被占满时将会触发Full GC,回收整个堆内存。

持久代:用于存放静态文件,比如java类、方法等。持久代对垃圾回收没有显著的影响。

回收效果图如下:

我这里之所以最后讲分代,是因为分代里涉及了前面几种算法。年轻代:涉及了复制算法;年老代:涉及了“标记-整理(Mark-Sweep)”的算法。

Android GC机制介绍相关推荐

  1. Android GC机制及一些调试信息

    在Davilk中,给程序分配的内存是根据机型厂商的不同而不同(现在大部分为32MB) 在VM内部会将内存分为:java使用的内存,Native使用的内存,他们之间不能共享,当某一方面不足 的时候必须向 ...

  2. Android签名机制介绍:生成keystore.签名.查看签名信息等方法

    为什么80%的码农都做不了架构师?>>>    Android独有的安全机制,除了权限机制外,另外一个就是签名机制了.签名机制主要用在以下两个主要场合起到其作用:升级App和权限检查 ...

  3. Android内存泄露和GC机制

    Android内存泄露和GC机制 本文先对Android内存垃圾回收机制进行介绍,之后对分析.定位内存泄露常用的测试方法进行总结,分享给大家. 一.Android内存垃圾回收(GC机制) 1.综述 A ...

  4. Android刷新机制-View绘制原理

    Android刷新机制-View绘制原理 Android刷新机制-SurfaceFlinger原理 Android刷新机制-Choreographer原理 一.概述 本文将从startActivity ...

  5. 32位jdk最大内存_你了解Java 内存区域和GC机制吗?

    目录 Java垃圾回收概况 Java内存区域 Java对象的访问方式 Java内存分配机制 Java GC机制 垃圾收集器 Java垃圾回收概况 Java GC(Garbage Collection, ...

  6. android binder机制之——(创建binder服务)

    Binder机制编程 前面的几篇文章具体介绍了android中binder机制的方方面面,相信你对binder机制已经有了较深刻的理解.俗话说得好"学以致用",以下我们就通过在an ...

  7. Android消息机制Handler用法

    这篇文章介绍了Android消息机制Handler用法总结,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧 1.简述 Handler消息机制主要包括: Messa ...

  8. 转载:Java 内存区域和GC机制

    原文链接:http://www.cnblogs.com/hnrainll/archive/2013/11/06/3410042.html 目录 Java垃圾回收概况 Java内存区域 Java对象的访 ...

  9. JVM内存管理及GC机制

    转载自:http://blog.csdn.net/suifeng3051/article/details/48292193 一.概述 Java GC(Garbage Collection,垃圾收集,垃 ...

  10. android handler的机制和原理_一文搞懂handler:彻底明白Android消息机制的原理及源码

    提起Android消息机制,想必都不陌生.其中包含三个部分:Handler,MessageQueue以及Looper,三者共同协作,完成消息机制的运行.本篇文章将由浅入深解析Android消息机制的运 ...

最新文章

  1. 谷歌发布TF新工具:计算速度提升2倍,减少无效参数
  2. class function,delphi静态函数的对象基址分析static
  3. 纠错编码基本实验matlab,纠错编码基本实验matlab实现包含源代码
  4. mysql数据库的F5_windows下mysql每天定时备份数据库几种方法
  5. java单纯形法_单纯形法 - fjzzq2002 - 博客园
  6. 凉了!张三同学没答好「进程间通信」,被面试官挂了....
  7. 树视图的属性与方法 c# 1614262746
  8. 中兴计算机专业,中兴计算机专业面试题.pdf
  9. python怎么编辑文件_关于python:如何在Google Colab中编辑和保存文本文件(.py)?
  10. python自学看什么书-如何自学Python ?自学看什么书比较好?
  11. OpenSource.com 评出 2014 年十佳开源软件
  12. Android Studio课堂总结05
  13. 体验魅力Cognos BI 10 系列,第1 部分: 第一次安装
  14. 静态路由特点及其配置
  15. 各种有意思的效应、法则、理论、逻辑、实验
  16. 多源最短路之大暴力算法(bushi
  17. k8s探针检测php,K8S教程(7)使用探针对容器进行健康检查
  18. 团队协作出了问题,项目经理怎么办?
  19. SAP 簇表 A017 物料信息记录 (指定工厂) 包含的透明表
  20. 第二届国信蓝点杯 c语言 本科组 赛题分析 第8题

热门文章

  1. 拉普拉斯变换公式表_MIT—微分方程笔记20 拉氏变换求解线性常微分方程
  2. cupsd进程_Linux进程基础
  3. 滑动平均_善杰告诉您初中物理学滑动变阻器的各种作用
  4. python字符串方法总结_python字符串函数总结
  5. 电脑投屏电视怎么设置_手机投屏怎么设置全屏
  6. GIS_gdal geotiff文件与JAVA 浮点二维数组array之间的转换
  7. 深度学习笔记_基本概念_卷积网络中的通道channel、特征图feature map、过滤器filter和卷积核kernel
  8. cartographer探秘第四章之代码解析(五) --- 后端优化 --- 闭环约束2 --- FastCorrelativeScanMatcher2D
  9. [开源]快速构建验证码
  10. 【贪心 哈夫曼树】bzoj2923: [Poi1998]The lightest language