Android 内存优化】垃圾回收算法 ( 内存优化总结 | 常见的内存泄漏场景 | GC 算法 | 标记清除算法 | 复制算法 | 标记压缩算法 )

简介: Android 内存优化】垃圾回收算法 ( 内存优化总结 | 常见的内存泄漏场景 | GC 算法 | 标记清除算法 | 复制算法 | 标记压缩算法 )

文章目录

一、 内存优化总结

二、 常见的内存泄漏场景

三、 内存回收算法

四、 标记-清除算法 ( mark-sweep )

五、 复制算法

六、 标记-压缩算法





一、 内存优化总结


内存泄漏原理 : 长生命周期对象 , 持有短生命周期对象的引用 , 并且是强引用持有 , GC 无法释放该短生命周期对象引用 , 造成 OOM ;


Android Profiler 工具参考官方文档 : 使用 Memory Profiler 查看 Java 堆和内存分配



使用 Memory Analyzer ( MAT ) 内存分析工具分析内存快照 , 首先要将内存快照文件 , 转化成 MAT 工具能识别的文件 , 然后使用 MAT 工具进行分析 ;



在博客 【Android 内存优化】Android Profiler 工具常用功能 ( 监测内存 | 内存快照 ) 中保存了内存快照文件 memory-20200625T145636.hprof , 要使用 MAT 工具分析该内存快照 , 需要先将该文件转换成为 MAT 标准的文件格式 ;



在博客 【Android 内存优化】使用 Memory Analyzer ( MAT ) 工具分析内存 ( hprof 文件转换 | MAT 工具下载 | MAT 工具使用 ) 中转换了 MAT 格式的内存快照 , 下载 Memory Analyzer ( MAT ) 内存分析工具 , 并在该工具中加载了 MAT 格式的文件 ;



在博客 【Android 内存优化】使用 Memory Analyzer ( MAT ) 工具分析内存 ( MAT 工具使用 | 最大对象 | 类实例个数 | 引用与被引用 | GC Roots 最短链 ) 中 使用 Memory Analyzer ( MAT ) 内存分析工具 中分析内存快照 , 主要是查看 GC Roots 最短链 , 分析出在哪个类中引用了该对象 ;






二、 常见的内存泄漏场景


内存泄漏的常见原因 :


集合的使用

静态成员

常量

单例模式 : 不要在单例中随便持有 Context , Activity 之类的成员 , 有极大的内存泄漏隐患 ;

没有释放或关闭的资源 : 如 IO 流 , Socket 等 ;

线程 : 界面退出 , 线程没有退出 , 线程持有的引用就泄漏了 ; 尽量在其中使用弱引用 ;

Handler : 非静态内部类造成内存泄漏 ;





三、 内存回收算法


1. 内存抖动 : 应用对象的内存 , 频繁的分配 , 回收 , 造成内存使用量上下抖动 , UI 卡顿 , 严重时甚至造成 OOM ( OutOfMemoryError ) , 造成内存溢出 ;



2. 内存抖动造成溢出原因 : 对象频繁分配 , 回收 , 会大量造成内存的空隙 , 这些空隙很小无法分配大块内存 , 当整个内存都是这种空隙时 , 无法为大块内存分配空间 , 就造成了 OOM 异常 ;



3. GC 垃圾回收之前 , 需要对内存对象进行采集 , 不同的虚拟机使用不同的垃圾回收算法 , 常用的垃圾回收算法 :


标记-清除算法 ( mark-sweep )

复制算法

标记-压缩算法

分代收集算法





四、 标记-清除算法 ( mark-sweep )


标记-清除算法 ( mark-sweep ) : 步骤分为两步 : ① 标记 , ② 清除 ;



内存中分为如下几块 :


可回收对象

存活对象

可用内存


标记-清除算法 ( mark-sweep ) 算法中 , 首先标记出可回收对象 , 标记完成之后 , 统一回收 ;


回收完毕后 , 存活的对象仍然保持在原来的位置 , 可用内存基本支离破碎 , 这样就会造成内存碎片 , 这些内存碎片中无法申请大块内存 ;


image.png


上图中的内存中 , 有 24 个格子的空闲内存 , 如果要申请 5 55 个单位格子的内存 , 发现无法申请 , 没有连续 5 个格子的内存 , 此时直接出现 OOM ;


有很多内存, 但都是支离破碎的 , 没有大块内存 ;






五、 复制算法


1. 复制算法 : 将可用内存 , 分为两个想等于内存区域块 , 区域 1 11 和 区域 2 22 , 使用时只使用其中的一个区域 ;


垃圾回收前 , 只使用区域 1 11 的内存

垃圾回收后 , 将区域 1 11 的内存中可用对象复制到区域 2 22

复制时的可用对象在区域 2 22 紧密排列 , 不留空隙

这样区域 2 22 中可用内存区域是大块完整的内存 , 不会产生内存碎片


当前使用区域 1 11 的内存区域内存不足时 , 会触发上述操作 , 将当前区域 1 11 的存活对象 , 拷贝到区域 2 22 中 , 然后清理区域 1 11 内存 ;


分配回收内存时 , 只需要按照顺序移动堆指针即可 , 不考虑碎片化等问题 , 简单 , 高效 ;




2. 弊端 :



该垃圾回收算法缺陷也很明显 , 就是会浪费一半内存空间 ;


有些对象的声明周期等同于应用声明周期 , 如 Android 中的 Application 等 , 该内存对象根本不释放 , 持续往返复制这类长生存期的对象 , 会极大降低效率 ;




image.png




六、 标记-压缩算法


1. 标记压缩算法 : 与标记清除算法都需要先进行标记 ;



2. 标记压缩算法流程 :


首先标记可回收对象

然后回收这些对象

最后整理存活对象 , 将其拷贝到一块连续内存中


该方法没有复制算法浪费一半内存的问题 ;


该方法因为多了一个压缩过程 , 因此有额外的开销 ;

image.png


目录
相关文章
|
30天前
|
Arthas 存储 算法
深入理解JVM,包含字节码文件,内存结构,垃圾回收,类的声明周期,类加载器
JVM全称是Java Virtual Machine-Java虚拟机JVM作用:本质上是一个运行在计算机上的程序,职责是运行Java字节码文件,编译为机器码交由计算机运行类的生命周期概述:类的生命周期描述了一个类加载,使用,卸载的整个过类的生命周期阶段:类的声明周期主要分为五个阶段:加载->连接->初始化->使用->卸载,其中连接中分为三个小阶段验证->准备->解析类加载器的定义:JVM提供类加载器给Java程序去获取类和接口字节码数据类加载器的作用:类加载器接受字节码文件。
202 55
|
3月前
|
消息中间件 存储 算法
JVM实战—3.JVM垃圾回收的算法和全流程
本文详细介绍了JVM内存管理与垃圾回收机制,涵盖以下内容:对象何时被垃圾回收、垃圾回收算法及其优劣、新生代和老年代的垃圾回收算法、Stop the World问题分析、核心流程梳理。
JVM实战—3.JVM垃圾回收的算法和全流程
|
6月前
|
缓存 监控 算法
Python内存管理:掌握对象的生命周期与垃圾回收机制####
本文深入探讨了Python中的内存管理机制,特别是对象的生命周期和垃圾回收过程。通过理解引用计数、标记-清除及分代收集等核心概念,帮助开发者优化程序性能,避免内存泄漏。 ####
141 3
|
7月前
|
算法 Java 开发者
Java内存管理与垃圾回收机制深度剖析####
本文深入探讨了Java虚拟机(JVM)的内存管理机制,特别是其垃圾回收机制的工作原理、算法及实践优化策略。不同于传统的摘要概述,本文将以一个虚拟的“城市环卫系统”为比喻,生动形象地揭示Java内存管理的奥秘,旨在帮助开发者更好地理解并调优Java应用的性能。 ####
|
7月前
|
缓存 算法 Java
本文聚焦于Java内存管理与调优,介绍Java内存模型、内存泄漏检测与预防、高效字符串拼接、数据结构优化及垃圾回收机制
在现代软件开发中,性能优化至关重要。本文聚焦于Java内存管理与调优,介绍Java内存模型、内存泄漏检测与预防、高效字符串拼接、数据结构优化及垃圾回收机制。通过调整垃圾回收器参数、优化堆大小与布局、使用对象池和缓存技术,开发者可显著提升应用性能和稳定性。
132 6
|
6月前
|
存储 监控 算法
Java内存管理的艺术:深入理解垃圾回收机制####
本文将引领读者探索Java虚拟机(JVM)中垃圾回收的奥秘,解析其背后的算法原理,通过实例揭示调优策略,旨在提升Java开发者对内存管理能力的认知,优化应用程序性能。 ####
110 0
|
7月前
|
算法 Java
JVM有哪些垃圾回收算法?
(1)标记清除算法: 标记不需要回收的对象,然后清除没有标记的对象,会造成许多内存碎片。 (2)复制算法: 将内存分为两块,只使用一块,进行垃圾回收时,先将存活的对象复制到另一块区域,然后清空之前的区域。用在新生代 (3)标记整理算法: 与标记清除算法类似,但是在标记之后,将存活对象向一端移动,然后清除边界外的垃圾对象。用在老年代
66 0
|
存储 编解码 缓存
|
存储 编解码 Android开发
Android内存优化-Bitmap内存优化
在日常开发中,我们不免会使用到Bitmap,而bitmap确实实在在的是内存使用的 “大户”,如何更好的使用 bitmap,减少其对 App内存的使用,是我们开发中不可回避的问题。
264 0
Android内存优化-Bitmap内存优化