【Android 内存优化】垃圾回收算法 ( 分代收集算法 | Serial 收集器 | ParNew 收集器 | Parallel Scavenge 收集器 | CMS 并发标记清除收集器 )

简介: 【Android 内存优化】垃圾回收算法 ( 分代收集算法 | Serial 收集器 | ParNew 收集器 | Parallel Scavenge 收集器 | CMS 并发标记清除收集器 )

文章目录

一、 分代收集算法

二、 垃圾回收器 / 收集器 ( GC )

三、 串行收集器 ( Serial )

四、 ParNew 收集器

五、 Parallel Scavenge 收集器

六、 CMS ( Concurrent Mark Sweep ) 并发标记清除收集器 ( 重点 )





一、 分代收集算法


1. 分代收集算法 : 每个对象的生命周期是不同的 , 某些对象如 Application 整个应用声明周期都存活 , 某些方法的局部变量对象 , 方法结束后 , 该局部对象就可以被回收了 , 不同声明周期的对象使用不同的垃圾回收算法 ;




2. Java 虚拟机的堆内存分区 :


年轻代 ( Yong Generation )

老年代 ( Old Generation )

持久代 ( Permanent Generation )



3. 年轻代内存区域 :



① 年轻代内存分为三块 :


Eden 区域

From 区域

To 区域

② 内存运行机制 : 新创建的对象 , 放在年轻代内存块中 , 开始时放在 Eden 区域 , 当 Eden 区域存满后 , 会将存活的对象转移到 From 区域 和 To 区域 ;

image.png





4. 老年代内存区域 :



① 对象晋升 : 对象每经过一次 GC 垃圾回收 , 其年龄就会加 1 11 ; 当年龄到达虚拟机设置的阈值之后 , 就会被放入老年代内存块中 ;


② 存放对象 : 老年代存放由年轻代晋升上来的对象 , 这是活得时间比较长的对象 ;




5. 持久代内存区域 : 主要存放类加载器 ( ClassLoader ) 加载的 Class , 常量池 , 等对象 ;

image.png







二、 垃圾回收器 / 收集器 ( GC )


1. GC 垃圾回收器 . 收集器 : 在 GC 中实现垃圾回收算法


年轻代内存区域的垃圾回收器 : Minor GC

老年代内存区域的垃圾回收器 : Major GC

整个内存区域的垃圾回收器 : Full GC

注意持久代内存区域的内存不回收 ;



年轻代内存区域与老年代内存区域的垃圾回收机制不同 ;



2. 年轻代又叫新生代 , 新生代内存区域的的垃圾回收器 :


Serial

ParNew

Parallel Scavenge


3. 老年代内存区域的垃圾回收器 :


CMS

Serial Old ( MSC )

Parallel Old





三、 串行收集器 ( Serial )


串行收集器 ( Serial ) : 新生代内存回收使用该回收机制 ;



① 运行内存区域 : Serial 串行垃圾回收器 在 年轻代 内存区域中收集要回收的内存 ;


② 垃圾回收算法 : 复制算法 ;


③ 运行机制 : 垃圾回收线程运行时 , 暂停用户线程 ;


④ 最基本 GC : Serial 串行垃圾回收器 , 这是最基本的垃圾回收器 , 老版本的 Java 虚拟机使用的就是这种垃圾回收器 ;


⑤ 特点 : 其工作时 , 是单线程 , 串行的 ;


⑥ 单线程执行 : 该垃圾回收器 , 需要暂停所有线程 , 使用单个线程处理回收多个线程的内存回收工作 ;


⑦ 暂停线程 : 执行垃圾回收时 , 必须暂停工作线程 , 直到垃圾收集结束后 , 才能绘制执行 ;


⑧ 安全点 : 停止工作线程的位置是 安全点 , 需要保存该位置的程序执行信息 ;


⑨ 优势 : 不需要处理多线程交互问题 ;



年轻代 , 复制算法 , 单线程 GC , 暂停用户线程






四、 ParNew 收集器


ParNew 收集器 :



① 运行区域 : ParNew 垃圾回收器 在 年轻代 内存区域中收集要回收的内存 ;


② 垃圾回收算法 : 复制算法 ;


③ 运行机制 : 垃圾回收线程运行时 , 暂停用户线程 ;


④ 多线程执行 : 该垃圾回收器 多线程运行 , 消耗时间要比 Serial 串行垃圾回收器要短 ;


⑤ 与 Serial 垃圾回收器对比 : 该 GC 是并行的 , 是 Serial 垃圾回收器的多线程版本 ;



年轻代 , 复制算法 , 多线程 GC , 暂停用户线程






五、 Parallel Scavenge 收集器


Parallel Scavenge 收集器 :



① 运行区域 : Parallel 垃圾回收器在 年轻代 内存区域中收集要回收的内存 ;


② 垃圾回收算法 : 复制算法 ;


③ 关注吞吐量 : Parallel 垃圾回收器 与 ParNew 垃圾回收器 区别是 , Parallel 垃圾回收器更关注吞吐量 ;


④ 吞吐量概念 : 吞吐量是 CPU 运行正常代码时间与总的消耗时间之间的比值 , CPU 运行的总时间是 程序运行时间 与 GC 垃圾收集的时间之和 ;


⑤ 吞吐量示例 : CPU 总共运行 100 秒 , 程序运行 95 秒 , 垃圾回收器运行 5 秒 , 那么吞吐量就是 95 100 = 0.95 \dfrac{95}{100} = 0.95

100

95


=0.95 ;



年轻代 , 复制算法 , 多线程 GC , 暂停用户线程 ( 关注吞吐量 )






六、 CMS ( Concurrent Mark Sweep ) 并发标记清除收集器 ( 重点 )


1. CMS 垃圾回收器 : 全称 Concurrent Mark Sweep , 并发标记清除收集器 ;


① 运行区域 : CMS 垃圾回收器在 老年代 内存区域中收集要回收的内存 ;


② 垃圾回收算法 : 标记-清除算法 , 会产生很多内存碎片 ;



2. 短暂停顿 : 在 GC 线程运行时 , 用户线程仅做最短的停顿 , 在停顿过程中主要用于标记内存 ;


由于其停顿时间是各个 GC 算法中最短 , 该并发标记清除收集器又叫 并发低延迟收集器 ;




3. CMS 收集器工作流程 ( 重点 ) : 要标记 3 33 次后 , 才可以执行清除操作 , 共 4 44 步骤 ;



① 初始标记 : 标记与 GC Roots 有引用链的对象 ; 该操作速度快 , 该步骤需要暂停用户线程 ;


② 并发标记 : GC Roots 追踪 , 从初始标记结果集合中标记出存活对象 , 不能保证所有的存活对象都被标记 ; 该步骤与应用程序并发执行 ;


③ 重新标记 : 上一步并发标记 GC 线程与用户程序并发期间的标记有部分变化 , 修正这部分标记信息 , 之后暂停用户线程 , 开始标记 ; 该暂停操作要比初始标记步骤暂停时间长 ;


④ 并发清除 : 回收所有 GC Roots 不可达对象 ;


上述四个步骤中 , 并发标记 , 并发清除 , 用时最长 , 但这两个与用户线程并发执行 , 因此可以看做该 CMS 垃圾收集器与用户线程是并发执行的 ;




4. CMS 收集器缺点 :



① CPU 性能消耗 : 多开线程 , 意味着 CPU 性能消耗多 ;


② 内存碎片 : 使用 标记-清除算法 , 会造成很多内存碎片 , 严重的话导致 OOM ;


③ 浮动垃圾 : 由于 GC 线程 与用户线程并发 造成的 , 在 GC 运行过程中产生的用户线程垃圾 , 需要等待下一次 GC 清理 , 这些垃圾就是浮动垃圾 ;




5 . Android 垃圾收集器 :



Android 中使用的是 CMS 垃圾回收器 , 会产生内存碎片 ;


Android 中内存抖动产生 OOM , 就是因为使用的是 CMS 垃圾回收器 ( 收集器 ) ;


Android 之所以采用标记-清除算法进行垃圾回收 , 是因为这种算法效率很高 , 性能对于嵌入式小型设备来说 , 非常重要 ; 大型服务器可以采用一些复杂的垃圾回收算法 , 如标记-压缩算法 , 该算法开销要高于标记-清除算法 ;


老年代 , 标记-清除算法 , 多线程 GC , 与用户线程并发 / 暂停


目录
相关文章
|
11月前
|
Prometheus 监控 算法
CMS圣经:CMS垃圾回收器的原理、调优,多标+漏标+浮动垃圾 分析与 研究
本文介绍了CMS(Concurrent Mark-Sweep)垃圾回收器的工作原理、优缺点及常见问题,并通过具体案例分析了其优化策略。重点探讨了CMS的各个阶段,包括标记、并发清理和重标记
CMS圣经:CMS垃圾回收器的原理、调优,多标+漏标+浮动垃圾 分析与 研究
|
存储 前端开发 Java
Android MVVM架构模式下如何避免内存泄漏
Android采用MVVM架构开发项目,如何避免内存泄漏风险?怎样避免内存泄漏?
448 1
|
9月前
|
缓存 编解码 Android开发
Android内存优化之图片优化
本文主要探讨Android开发中的图片优化问题,包括图片优化的重要性、OOM错误的成因及解决方法、Android支持的图片格式及其特点。同时介绍了图片储存优化的三种方式:尺寸优化、质量压缩和内存重用,并详细讲解了相关的实现方法与属性。此外,还分析了图片加载优化策略,如异步加载、缓存机制、懒加载等,并结合多级缓存流程提升性能。最后对比了几大主流图片加载框架(Universal ImageLoader、Picasso、Glide、Fresco)的特点与适用场景,重点推荐Fresco在处理大图、动图时的优异表现。这些内容为开发者提供了全面的图片优化解决方案。
375 1
|
监控 Oracle Java
JDK 21中的分代ZGC:一场内存管理的革命
JDK 21引入了分代ZGC,为Java应用程序的内存管理带来了革命性的进步。分代ZGC通过将堆内存划分为年轻代和老年代,采用并发处理和染色指针技术,实现了高吞吐量、低延迟和更好的可扩展性。这一特性显著提升了系统的性能和稳定性。
1339 51
|
12月前
|
算法 安全 Java
即时通讯安全篇(一):正确地理解和使用Android端加密算法
本文主要讨论针对Android这样的移动端应用开发时,如何正确的理解目前常用的加密算法,为诸如即时通讯应用的实战开发,如何在合适的场景下选择适合的算法,提供一些参考。
380 0
|
监控 Java Android开发
深入探讨Android系统的内存管理机制
本文将深入分析Android系统的内存管理机制,包括其内存分配、回收策略以及常见的内存泄漏问题。通过对这些方面的详细讨论,读者可以更好地理解Android系统如何高效地管理内存资源,从而提高应用程序的性能和稳定性。
593 16
|
缓存 算法 Java
JVM知识体系学习六:JVM垃圾是什么、GC常用垃圾清除算法、堆内存逻辑分区、栈上分配、对象何时进入老年代、有关老年代新生代的两个问题、常见的垃圾回收器、CMS
这篇文章详细介绍了Java虚拟机(JVM)中的垃圾回收机制,包括垃圾的定义、垃圾回收算法、堆内存的逻辑分区、对象的内存分配和回收过程,以及不同垃圾回收器的工作原理和参数设置。
980 4
JVM知识体系学习六:JVM垃圾是什么、GC常用垃圾清除算法、堆内存逻辑分区、栈上分配、对象何时进入老年代、有关老年代新生代的两个问题、常见的垃圾回收器、CMS
|
监控 Java Android开发
深入探索Android系统的内存管理机制
本文旨在全面解析Android系统的内存管理机制,包括其工作原理、常见问题及其解决方案。通过对Android内存模型的深入分析,本文将帮助开发者更好地理解内存分配、回收以及优化策略,从而提高应用性能和用户体验。
|
程序员 开发者
分代回收和手动内存管理相比有何优势
分代回收和手动内存管理相比有何优势
|
监控 算法 数据可视化
深入解析Android应用开发中的高效内存管理策略在移动应用开发领域,Android平台因其开放性和灵活性备受开发者青睐。然而,随之而来的是内存管理的复杂性,这对开发者提出了更高的要求。高效的内存管理不仅能够提升应用的性能,还能有效避免因内存泄漏导致的应用崩溃。本文将探讨Android应用开发中的内存管理问题,并提供一系列实用的优化策略,帮助开发者打造更稳定、更高效的应用。
在Android开发中,内存管理是一个绕不开的话题。良好的内存管理机制不仅可以提高应用的运行效率,还能有效预防内存泄漏和过度消耗,从而延长电池寿命并提升用户体验。本文从Android内存管理的基本原理出发,详细讨论了几种常见的内存管理技巧,包括内存泄漏的检测与修复、内存分配与回收的优化方法,以及如何通过合理的编程习惯减少内存开销。通过对这些内容的阐述,旨在为Android开发者提供一套系统化的内存优化指南,助力开发出更加流畅稳定的应用。
481 31