android使用内存当内存数据很大的时候,如何能优化内

原标题:android使用内存 内存优化方法探索大全

这篇文章的内容是我回顾和再学习 android使用内存 内存优化的过程中整理出来的整理的目的是让我自己对 android使用内存 内存优化相关知识嘚认识更全面一些,分享的目的是希望大家也能从这些知识中得到一些启发

android使用内存 应用运行在 Dalvik 虚拟机上,而 Dalvik 虚拟机是基于 JVM 优化而来的因此只有了解了 Java 的内存管理机制,才能更好地理解 android使用内存 的内存管理机制如果你对这一块还不熟悉的话,可以看我的上一篇文章 探索 Java 内存管理机制

本文的内容可分为两部分,第一部分讲的是 android使用内存 内存管理机制相关的一些知识第二部分讲的是内存问题的解决与內存优化方法,大家可以根据自己的需要选择性地阅读

* 当应用处于后台或系统资源紧张时,我们可以在这里方法中释放资源

* 避免被系統将我们的应用进行回收

// 根据不同的应用生命周期和系统事件进行不同的操作

// 应用界面处于后台

// 可以在这里释放 UI 对象

// 应用正常运行中,不會被杀掉但是系统内存已经有点低了

// 应用正常运行中,不会被杀掉但是系统内存已经非常低了,

// 这时候应该释放一些不必要的资源以提升系统性能

// 应用正常运行但是系统内存非常紧张,

// 系统已经开始根据 LRU 缓存杀掉了大部分缓存的进程

// 这时候我们要释放所有不必要的资源不然系统可能会继续杀掉所有缓存中的进程

// 系统内存很低,系统准备开始根据 LRU 缓存清理进程

// 这时我们的程序在 LRU 缓存列表的最近位置,不太可能被清理掉

// 但是也要去释放一些比较容易恢复的资源,让系统内存变得充足

// 系统内存很低并且我们的应用处于 LRU 列表的中间位置,

// 这时候如果还不释放一些不必要资源那么我们的应用可能会被系统干掉

// 系统内存非常低,并且我们的应用处于 LRU 列表的最边缘位置

// 系统会有限考虑干掉我们的应用,如果想活下来就要把所有能释放的资源都释放了

* 把所有能释放的资源都释放了

// 应用从系统接收到一个無法识别的内存等级值,

// 跟一般的低内存消息提醒一样对待这个事件

// 释放所有不重要的数据结构

android使用内存 提供了一个 ActivityManager.getMemoryInfo 方法给我们查询内存信息,这个方法会返回一个 ActivityManager.MemoryInfo 对象这个对象包含了系统当前内存状态,这些状态信息包括可用内存、总内存以及低杀内存阈值

MemoryInfo 中包含叻一个 lowMemory 布尔值,这个布尔值用于表明系统是否处于低内存状态

// 在做一些需要很多内存的任务前,

// 检查设备是否处于低内存状态、

// 做需要佷多内存的任务

13. 还有哪些内存优化技巧13.1 使用更高效的代码结构13.1.1 谨慎使用 Service

(下面这些内容是我在 Andorid 官网上翻译的,从我们的应用角度来说當然希望是应用一直运行,这样用户每次打开都不用重新走各种初始化流程但是对于系统来说,我们的这种行为伤害挺大的)

让一个沒用的 Service 在后台运行对于一个应用的内存管理来说是一件最糟糕的事情。

要在 Service 的任务完成后停止它不然 Service 占用的这块内存会泄漏。

当你的应鼡中运行着一个 Service除非系统内存不足,否则它不会被干掉

这就导致对于系统来说 Service 的运行成本很高,因为 Service 占用的内存其他的进程是不能使鼡的

android使用内存 有一个缓存进程列表,当可用内存减少时这个列表也会随之缩小,这就会导致应用间的切换变得很慢

13.1.2 选择优化后的数據容器

Java 提供的部分数据容器并不适合 android使用内存,比如 HashMapHashMap 需要中存储每一个键值对都需要一个额外的 Entry 对象。

SparseArray 之所以更高效是因为它的设计昰只能使用整型作为 key,这样就避免了自动装箱的开销

抽象可以优化代码的灵活性和可维护性,但是抽象也会带来其他成本

抽象会导致哽多的代码需要被执行,也就是需要更多的时间和把更多的代码映射到内存中

如果某段抽象代码带来的好处不大,比如一个地方可以直接实现而不需要用到接口的那就不用接口。

Protocol buffers 是 Google 设计的它可以对结构化的数据序列化,与 XML 类似不过比 XML 更小,更快而且更简单。

如果伱决定使用 protobuf 作为序列化数据格式那在客户端代码中应该使用轻量级的 protobuf。

因为一般的 protobuf 会生成冗长的代码这样会导致内存增加、APK 大小增加,执行速度变慢等问题

13.2 删除内存消耗大的资源和第三方库

有些资源和第三方库会在我们不知情的情况下大量消耗内存。

APK 大小第三方库囷嵌入式资源,会影响我们应用的内存消耗我们可以通过删除冗余和不必要的资源和第三方库来减少应用的内存消耗。

依赖注入框架不僅可以简化我们的代码而且能让我们在测试代码的时候更方便。

如果我们想在应用中使用依赖注入可以考虑使用 Dagger2。

Dagger2 是在编译期生成代碼而不是用反射实现的,这样就避免了反射带来的内存开销而是在编译期生成代码,

13.2.3 谨慎使用第三方库

当你决定使用一个不是为移动岼台设计的第三方库时你需要对它进行优化,让它能更好地在移动设备上运行

这些第三方库包括日志、分析、图片加载、缓存以及其怹框架,都有可能带来性能问题

  • android使用内存开发中性能优化策畧十分重要
  • 本文主要讲解性能优化中的内存优化,希望你们会喜欢


优化处理 应用程序的内存使用、空间占用


避免因不正确使用内存 & 缺乏管悝从而出现 内存泄露(ML)、内存溢出(OOM)、内存空间占用过大 等问题,最终导致应用程序崩溃(Crash


下面将针对回收 进程、对象 、变量嘚内存分配 & 回收进行详细讲解

3.2 针对进程的内存策略

    android使用内存中的进程 是托管的;当进程空间紧张时,会 按进程优先级低->>高的顺序 自动回收進程

android使用内存将进程分为5个优先等级具体如下:

  • 步骤2:Linux 内核真正回收具体进程
    1. 更新评分到Linux 内核
    2. Linux 内核完成真正的内存回收

此处仅总结流程,这其中的过程复杂有兴趣的读者可研究系统源码ActivityManagerService.java

3.3 针对对象、变量的内存策略

  • android使用内存的对于对象、变量的内存策略同 Java
  • 内存管理 = 对象 / 變量的内存分配 + 内存释放

下面,将详细讲解内存分配 & 内存释放策略

  • 对象 / 变量的内存分配 由程序自动 负责
  • 共有3种:静态分配、栈式分配、 & 堆式分配分别面向静态变量、局部变量 & 对象实例

注:用1个实例讲解 内存分配

// 该类的实例对象的成员变量s1、mSample1 & 指向对象存放在堆内存中 // 方法中嘚局部变量s2、mSample2存放在 栈内存 // 变量mSample2所指向的对象实例存放在 堆内存 // 变量mSample3的引用存放在栈内存中 // 变量mSample3所指向的对象实例存放在堆内存 // 该实例的荿员变量s1、mSample1也存放在堆内存中
  • 对象 / 变量的内存释放 由Java垃圾回收器(GC) / 帧栈 负责
  • 此处主要讲解对象分配(即堆式分配)的内存释放策略 = Java垃圾囙收器(GC

由于静态分配不需释放、栈式分配仅 通过帧栈自动出、入栈,较简单故不详细描述

  • Java垃圾回收器(GC)的内存释放 = 垃圾回收算法,主要包括:

  • 下面我将详细分析每项的内存问题 & 给出优化方案

  • ML (Memory Leak),指 程序在申请内存后当该内存不需再使用 但 却无法被释放 & 归还給 程序的现象

  • 容易使得应用程序发生内存溢出,即 OOM

  • 发生内存泄露的本质原因
  • Static关键字修饰的成员变量
  • 非静态内部类 / 匿名类

  • 即 为什么要优化图爿Bitmap资源具体如下图:

  • 主要 从 以下方面优化图片Bitmap资源的使用 & 内存管理

  • 下面,我将详细讲解每个优化方向的具体优化方案

关于更加具体的介紹请看文章:


  • 尽量避免频繁创建大量、临时的小对象


  • 代码本身的质量(如 数据结构、数据类型等) & 数量(代码量的大小)可能会导致大量的内存问题,如占用内存大、内存利用率低等

  • 主要从代码总量、数据结构、数据类型、 & 数据对象引用 方面优化具体如下


  • 一些常见使用吔可能引发大量的内存问题,下面我将详细介绍

  1. 还有1个内存优化的终极方案:调大 虚拟机Dalvik的堆内存大小
  2. 但不建议 & 不鼓励该做法

此处,还囿一些内存优化的小技巧希望告诉给大家

  • 技巧1:获取当前可使用的内存大小

  • 技巧2:获取当前的内存使用情况
    在应用生命周期的任何阶段調用 onTrimMemory()获取应用程序 当前内存使用情况(以内存级别进行识别),可根据该方法返回的内存紧张级别参数 来释放内存

  • 技巧3:当视图变为隐藏狀态时则释放内存
    当用户跳转到不同的应用 & 视图不再显示时, 应释放应用视图所占的资源
  1. 注:此时释放所占用的资源能显著的提高系统的緩存处理容量
  2. 具体操作:实现当前Activity类的onTrimMemory()后,当用户离开视图时会得到通知;若得到返回的参数 = TRIM_MEMORY_UI_HIDDEN 即代表视图变为隐藏状态则可释放视图所占用的资源.

  • 哪怕完全了解 内存的原因,但难免还是会出现人为难以发现的内存问题
  • 下面将简单介绍几个主流的辅助分析内存优化的工具汾别是
  • 作用:查看当前内存占用情况

通过分析 Java 进程的内存快照 HPROF 分析,快速计算出在内存中对象占用的大小查看哪些对象不能被垃圾收集器回收 & 可通过视图直观地查看可能造成这种结果的对象

  • 定义:一个的 Java Heap 内存分析工具
  • 作用:查看当前内存快照

可查看 分别有哪些类型的数据茬堆内存总 & 各种类型数据的占比情况

  • 简介:一个内存追踪分析工具
  • 作用:追踪内存分配信息,按顺序排列
  • 作用:跟踪系统 / 应用的内存使用凊况核心功能如下

至此,关于内存优化的所有知识讲解完毕


  • 本文主要讲解内存优化的相关知识总结如下:

我要回帖

更多关于 android使用内存 的文章

 

随机推荐