我的编程空间,编程开发者的网络收藏夹
学习永远不晚

Android内存泄漏终极解决篇(上)

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

Android内存泄漏终极解决篇(上)

一、概述
在Android的开发中,经常听到“内存泄漏”这个词。“内存泄漏”就是一个对象已经不需要再使用了,但是因为其它的对象持有该对象的引用,导致它的内存不能被回收。“内存泄漏”的慢慢积累,最终会导致OOM的发生,千里之堤,毁于蚁穴。所以在写代码的过程中,应该要注意规避会导致“内存泄漏”的代码写法,提高软件的健壮性。
本文将从发现问题、解决问题、总结问题的三个角度出发,循序渐进,彻底解决“内存泄漏”的问题。

二、内存泄漏的检查工具Heap

工欲善其事必先利其器,要检测“内存泄漏”的发生,需要借助DDMS中的Heap工具及MAT工具,Heap工具用于大致分析是否存在“内存泄漏”,而MAT工具则用于分析“内存泄漏”发生在哪里。

Heap工具的使用介绍

这里写图片描述

具体操作

1.在Devices设备列表中,找到你所在的设备,点击你想要监控的进程。 2.点击“Update Heap”按钮更新堆内存的情况。 3.点击“Heap”视图,查看内存的情况。 4.每次在Activity的退出和进入的时候点击“Cause GC”,手动调用GC释放应用的内存。 5.观察data oject那一行,每一次点击“Casue GC”的时候,观察Total Size的值,如果该值不断增加,则说明该应用程序存在“内存泄漏”。

我们先模拟一下内存泄漏,然后通过Heap工具来判断一下是否存在内存泄漏。
上一段存在内存泄漏的代码:


public class LeakAty extends Activity {
 @Override
 protected void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.aty_leak);
  testLeak();
 }
 
 private void testLeak() {
  new Thread(new Runnable() {
   @Override
   public void run() {
    while (true) {
     try {
      Thread.sleep(1000);
     } catch (InterruptedException e) {
      e.printStackTrace();
     }
    }
   }
  }).start();
 }

上述的代码存在内存泄漏,new Runnable(){}是一个非静态的匿名内部类,所以它会强引用创建它的外围对象LeakAty,我们来测试一下内存泄漏的过程,开启手机的方向旋转功能,不断地旋转手机,让LeakAty不断地创建新的实例。理论上如果不存在上述泄漏的代码,之前的Activity会在onDestory之后被回收内存。而一旦存在上述泄漏的代码,新创建的Ruannale实例会一直处于运行状态,它不会被回收,而它强引用的LeakAty当然也不会被回收,所以在屏幕不断旋转,之前创建的LeakAty就不会被释放,会导致旋转n次,内存中就存在n+1个的LeakAty实例。
Heap工具第一次按下Cause GC按钮的截图:

这里写图片描述 

上图的data object的Total Size的大小为1.031M。经过多次的旋转屏幕之后,我们再看一下截图

这里写图片描述 

Total Size变成了2.059M,从1.031M到2.059M,每次调用GC的过程中data object的总大小没有回落,所以可以证实上面的代码确实是存在内存泄漏的问题,那么泄漏发生在哪里?答案可以通过MAT工具来分析得到。

三、内存泄漏的分析工具MAT

要通过MAT分析,需要提供一个.hprof文件。我们可以通过”Dump HPROF file”按钮转存当前的堆内存信息。我们将其保存为1.hprof。

这里写图片描述

导出的1.hprof的格式需要通过..\sdk\tools\目录下的hprof-conv.exe工具进行转换才能被MAT成功导入,我们将其转换成out1.hprof
这里写图片描述

将out1.hprof导入到MAT工具中,File->Open Heap Dump…

这里写图片描述

点击左边的标签Overview,Actions->Histogram

这里写图片描述

在Histogram界面中,因为我们想要知道Activity是否泄漏了,所以输入关键词Activity,然后按下回车键。

这里写图片描述

之后便可以得到Activity的相关的搜索结果,下图的搜索结果中Activity的实例有7个。点击选中下图标红色框框的地方,右键->Merge Shortest Paths to GC Roots->exclude all phantom/weak/soft etc. references。排除虚引用、弱引用、软引用的实例,剩下的都是强引用实例。

这里写图片描述

从过滤出来的强引用的列表中,我们可以看到这七个实例都是被Thread所引用了。所以证实上面的代码确实存在内存泄漏。

这里写图片描述

四、本文总结

内存泄漏检测可以使用Heap工具,内存分析可以使用MAT工具。本文的案例中提到了一种内存泄漏的情况,就是非静态内部类的对象会强引用其外围对象,一旦这个非静态内部类的实例没有释放,它的外围对象也不会释放,所以就会造成内存泄漏。下篇将具体探讨一下,在Android的开发过程中,哪些写法容易造成内存泄漏,该如何解决?请阅读Android内存泄漏终极解决篇(下)。

您可能感兴趣的文章:Android Studio 3.0上分析内存泄漏的原因Android内存泄漏终极解决篇(下)Android性能优化之利用强大的LeakCanary检测内存泄漏及解决办法Android 有效的解决内存泄漏的问题实例详解Android性能优化之利用Rxlifecycle解决RxJava内存泄漏详解Android开发:浅谈MVP模式应用与内存泄漏问题解决浅谈Android应用的内存优化及Handler的内存泄漏问题Android 内存泄漏的几种可能总结详解Android内存泄漏检测与MAT使用Android内存泄漏的轻松解决方法


免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

Android内存泄漏终极解决篇(上)

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

Android内存泄漏终极解决篇(上)

一、概述 在Android的开发中,经常听到“内存泄漏”这个词。“内存泄漏”就是一个对象已经不需要再使用了,但是因为其它的对象持有该对象的引用,导致它的内存不能被回收。“内存泄漏”的慢慢积累,最终会导致OOM的发生,千里之堤,毁于蚁穴。所以
2022-06-06

Android内存泄漏终极解决篇(下)

一、概述 在 Android内存泄漏终极解决篇(上)中我们介绍了如何检查一个App是否存在内存泄漏的问题,本篇将总结典型的内存泄漏的代码,并给出对应的解决方案。内存泄漏的主要问题可以分为以下几种类型:静态变量引起的内存泄漏非静态内部类引起的
2022-06-06

android handler内存泄漏怎么解决

在Android中,Handler的使用很容易引发内存泄漏问题。以下是一些解决内存泄漏的方法:1. 使用静态内部类:将Handler定义为Activity的静态内部类,并将Activity的弱引用保存在Handler中,这样可以避免Hand
2023-09-15

PHP 内存泄漏检测:识别和解决内存泄漏

答案:php 内存泄漏是循环引用引起的,导致应用程序占用内存越来越多。步骤:检测内存泄漏:使用 debug_backtrace()、xdebug 或 php-gc 等工具。实战案例:循环引用会导致内存泄漏,如:objecta 和 objec
PHP 内存泄漏检测:识别和解决内存泄漏
2024-05-11

android内存溢出和内存泄漏问题怎么解决

Android内存溢出和内存泄漏是常见的问题,可以通过以下方法来解决:1. 使用内存分析工具:可以使用Android Studio自带的Memory Profiler或者第三方工具(如MAT、LeakCanary)来分析和监测内存使用情况,
2023-08-26

android内存泄漏的解决方式有哪些

解决Android内存泄漏的方式有以下几种:1. 避免使用静态变量:静态变量的生命周期与应用程序的生命周期相同,如果不及时释放,会导致内存泄漏。2. 及时释放资源:对于一些需要手动释放的资源,如文件流、数据库连接等,需要在不再使用时及时关闭
2023-09-09

java内存泄漏如何解决

今天小编给大家分享一下java内存泄漏如何解决的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。1、单例引起的内存泄漏。,由于单
2023-06-30

tomcat内存泄漏如何解决

解决Tomcat内存泄漏的方法有以下几种:1. 修复代码:通过检查代码,找到并修复可能引起内存泄漏的问题,例如没有正确关闭资源或者使用了不合理的数据结构等。2. 使用垃圾回收机制:Java有自动垃圾回收机制,可以自动释放不再使用的内存。可以
2023-08-19

怎么解决Linux内核内存泄漏

这篇文章主要讲解了“怎么解决Linux内核内存泄漏”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“怎么解决Linux内核内存泄漏”吧!什么是内存泄漏:程序向系统申请内存,使用完不需要之后,不释
2023-06-15

怎么解决内存泄漏问题

本篇内容介绍了“怎么解决内存泄漏问题”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!问题排查首先确定内存泄漏问题出现的时间,发现在该时间点的上
2023-06-16

详解Android Handler 机制 (三)内存泄漏

ps:看本文之前最好先了解一下Handler源码 常用写法 我们一般使用Handler使用匿名内部类的写法,也就是: private Handler mHandler = new Handler() {@Overridepublic voi
2022-06-06

Android Studio 3.0上内存泄漏的示例分析

这篇文章主要为大家展示了“Android Studio 3.0上内存泄漏的示例分析”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“Android Studio 3.0上内存泄漏的示例分析”这篇文章
2023-05-30

如何解决JAVA内存泄漏问题

本篇内容介绍了“如何解决JAVA内存泄漏问题”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!目录1、什么是内存泄漏2、内存泄漏的原因3、内存泄
2023-06-20

java内存泄漏问题怎么解决

这篇文章主要介绍“java内存泄漏问题怎么解决”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“java内存泄漏问题怎么解决”文章能帮助大家解决问题。1、概念Java中的内存泄露是指不再使用的对象的内存
2023-06-30

drawimage内存泄漏问题怎么解决

解决drawImage内存泄漏问题的方法如下:1. 及时释放资源:使用完image对象后,可以调用`image = null;`来手动释放内存。2. 使用try-finally语句块:在使用image对象的代码块中,使用try-finall
2023-09-05

Gomap发生内存泄漏解决方法

这篇文章主要介绍了Gomap发生内存泄漏解决方法详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
2022-11-16

详解Android性能优化之内存泄漏

综述 内存泄漏(memory leak)是指由于疏忽或错误造成程序未能释放已经不再使用的内存。那么在Android中,当一个对象持有Activity的引用,如果该对象不能被系统回收,那么当这个Activity不再使用时,这个Activity
2022-06-06

Android 5.1应用中 WebView出现内存泄漏如何解决

今天就跟大家聊聊有关Android 5.1应用中 WebView出现内存泄漏如何解决,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。问题背景在排查项目内存泄漏过程中发现了一些由WebV
2023-05-31

java内存泄漏怎么查看和解决

Java内存泄漏是指程序中存在无用的对象占用内存,但无法被垃圾回收器回收。以下是查看和解决Java内存泄漏的一些建议:1. 使用内存分析工具:使用工具如Eclipse Memory Analyzer(MAT)或Java VisualVM等,
2023-09-12

编程热搜

  • Android:VolumeShaper
    VolumeShaper(支持版本改一下,minsdkversion:26,android8.0(api26)进一步学习对声音的编辑,可以让音频的声音有变化的播放 VolumeShaper.Configuration的三个参数 durati
    Android:VolumeShaper
  • Android崩溃异常捕获方法
    开发中最让人头疼的是应用突然爆炸,然后跳回到桌面。而且我们常常不知道这种状况会何时出现,在应用调试阶段还好,还可以通过调试工具的日志查看错误出现在哪里。但平时使用的时候给你闹崩溃,那你就欲哭无泪了。 那么今天主要讲一下如何去捕捉系统出现的U
    Android崩溃异常捕获方法
  • android开发教程之获取power_profile.xml文件的方法(android运行时能耗值)
    系统的设置–>电池–>使用情况中,统计的能耗的使用情况也是以power_profile.xml的value作为基础参数的1、我的手机中power_profile.xml的内容: HTC t328w代码如下:
    android开发教程之获取power_profile.xml文件的方法(android运行时能耗值)
  • Android SQLite数据库基本操作方法
    程序的最主要的功能在于对数据进行操作,通过对数据进行操作来实现某个功能。而数据库就是很重要的一个方面的,Android中内置了小巧轻便,功能却很强的一个数据库–SQLite数据库。那么就来看一下在Android程序中怎么去操作SQLite数
    Android SQLite数据库基本操作方法
  • ubuntu21.04怎么创建桌面快捷图标?ubuntu软件放到桌面的技巧
    工作的时候为了方便直接打开编辑文件,一些常用的软件或者文件我们会放在桌面,但是在ubuntu20.04下直接直接拖拽文件到桌面根本没有效果,在进入桌面后发现软件列表中的软件只能收藏到面板,无法复制到桌面使用,不知道为什么会这样,似乎并不是很
    ubuntu21.04怎么创建桌面快捷图标?ubuntu软件放到桌面的技巧
  • android获取当前手机号示例程序
    代码如下: public String getLocalNumber() { TelephonyManager tManager =
    android获取当前手机号示例程序
  • Android音视频开发(三)TextureView
    简介 TextureView与SurfaceView类似,可用于显示视频或OpenGL场景。 与SurfaceView的区别 SurfaceView不能使用变换和缩放等操作,不能叠加(Overlay)两个SurfaceView。 Textu
    Android音视频开发(三)TextureView
  • android获取屏幕高度和宽度的实现方法
    本文实例讲述了android获取屏幕高度和宽度的实现方法。分享给大家供大家参考。具体分析如下: 我们需要获取Android手机或Pad的屏幕的物理尺寸,以便于界面的设计或是其他功能的实现。下面就介绍讲一讲如何获取屏幕的物理尺寸 下面的代码即
    android获取屏幕高度和宽度的实现方法
  • Android自定义popupwindow实例代码
    先来看看效果图:一、布局
  • Android第一次实验
    一、实验原理 1.1实验目标 编程实现用户名与密码的存储与调用。 1.2实验要求 设计用户登录界面、登录成功界面、用户注册界面,用户注册时,将其用户名、密码保存到SharedPreference中,登录时输入用户名、密码,读取SharedP
    Android第一次实验

目录