搜索
查看
编辑修改
首页
UNITY
NODEJS
PYTHON
AI
GIT
PHP
GO
CEF3
JAVA
HTML
CSS
搜索
我家自动化
这个屌丝很懒,什么也没留下!
关注作者
热门标签
jquery
HTML
CSS
PHP
ASP
PYTHON
GO
AI
C
C++
C#
PHOTOSHOP
UNITY
iOS
android
vue
xml
爬虫
SEO
LINUX
WINDOWS
JAVA
MFC
CEF3
CAD
NODEJS
GIT
Pyppeteer
article
热门文章
1
初始&安装RabbitMQ
2
c语言 printf_[每日C语言」printf()函数的修饰符和返回值
3
【mqtt】client测试工具使用_mqttfx-1.7.1-windows-x64
4
Python函数(三):闭包、装饰器_下面定义了一个使用多个装饰器修饰的函数,具体如下: @wrap_three @wrap_two @w
5
鸿蒙(HarmonyOS)应用开发——应用程序入口UIAbility(题目答案)_harmonyos3.0应用开发系列课答案
6
虹科Workshop丨2月29日与南高齿开展风电齿轮箱技术交流会,共拓风电行业未来!
7
简单实现视频直播_直播服务器地址
8
美团最新!FastPillars:基于Pillar的最强3D检测落地方案
9
堆排序(向下调整法,向上调整法详解)
10
论文《Graph Neural Networks for Social Recommendation》阅读_graphrec
当前位置:
article
> 正文
android常见内存泄漏主要有以下几类:_集合类泄漏 android
作者:我家自动化 | 2024-03-15 11:12:40
赞
踩
集合类泄漏 android
一、Handler 引起的内存泄漏。
在Android开发中,我们经常会使用Handler来控制主线程UI程序的界面变化,使用非常简单方便,但是稍不注意,很容易引发内存泄漏。
我们知道,Handler、Message、MessageQueue是相互关联在一起的,Handler通过发送消息Message与主线程进行交互,如果Handler发送的消息Message尚未被处理,该Message及发送它的Handler对象将被MessageQueue一直持有,这样就可能会导致Handler无法被回收。
请看下面的代码:
SecondActivity
代码中有一个延迟
1
秒执行的消息Message,当界面从SecondActivity跳转到ThirdActivity时,SecondActivity自动进入后台,此时如果系统资源紧张(或者打开设置里面的“不保留活动”选项),SecondActivity将会被finish。但问题来了,由于SecondActivity的Handler对象mHandler为非静态匿名内部类对象,它会自动持有外部类SecondActivity的引用,从而导致SecondActivity无法被回收,造成内存泄漏。
解决办法:将Handler声明为静态内部类,就不会持有外部类SecondActivity的引用,其生命周期就和外部类无关,如果Handler里面需要context的话,可以通过弱引用方式引用外部类。参考代码如下:
通过上面的方法,创建一个静态Handler内部类,其持有的对象context使用弱引用,可以避免SecondActivity内存泄漏,但是Looper线程的消息队列中可能还有待处理的消息,所以在Activity的onDestroy方法中,还要记住移除消息队列中待处理的消息。参考代码如下:
Hander
提供了如下方法移除消息队列中的消息。
public
final void
removeCallbacks
(Runnable r)
;
public
final void
removeCallbacks
(Runnable r, Objecttoken)
;
public
final void
removeMessages
(int what)
;
public
final void
removeMessages
(int what, Object object)
;
public
final void
removeCallbacksAndMessages
(Object token)
;
二、单例模式引起的内存泄漏
由于单例的生命周期是和app的生命周期一致的,如果使用不当很容易引发内存泄漏。如下代码:
这是一个单例模式的标准写法,表面上看没有任何问题,但是细心的同学会发现,构建该单例的一个实例时需要传入一个Context,此时传入的Context就非常关键,如果此时传入的是Activity,由于Context会被创建的实例一直持有,当Activity进入后台或者开启设置里面的不保留活动时,Activity会被销毁,但是单例持有它的Context引用,Activity又没法销毁,导致了内存泄漏。
如果此时传入的Context是ApplicationContext,由于ApplicationContext的生命周期是和app一致的,不会导致内存泄漏。但是我们不能指望使用这个单例的用户始终传入期望的Context,因此需要对这个单例设计进行调整,可以在构造函数中对mContext赋值改为
this
.mContext = context.getApplicationContext;当然,也可以直接不让用户传入context。
参考解决办法:
1
、一般在我们开发的应用中,都会实现Application,在里面做一些全局性的事情。可以在该实现里面对外提供一个单例,通过此实例来获取ApplicationContext。代码如下:
2
、重构Singleton,把构建单例时的context去掉,避免外面使用的人传入错误参数,代码如下:
三、非静态内部类创建静态实例引起的内存泄漏
请看下面的代码:
app
的生命周期是一致的。在某些场景,如Activity需要频繁切换,需要不断加载大量图片的场合,是会出现上述代码的,每次Activity启动之后都会使用该单例,避免重复一些有压力的操作。但是这样会引起内存泄漏,因为非静态的内部类InnerClass会自动持有外部类SecondActivity2的引用,创建的静态实例mInner就会一直持有SecondActivity2的引用,导致SecondActivity2需要销毁的时候没法正常销毁。
怎么知道静态实例mInner持有SecondActivity2的引用呢?debug程序之后你会清晰的发现静态实例mInner确实持有外部类SecondActivity2的引用,见下图:
上述代码的正确做法是把内部类InnerClass修改为静态的就可以避免内存泄漏了,因为静态内部类InnerClass不在持有外部类SecondActivity2的引用了。见下图:
当然,也可以把InnerClass单独抽出来作为一个内,写成单例模式,完成同样的功能,同时也可以避免内存泄漏。
四、非静态匿名内部类引起的内存泄漏
在android开发中,相信大家都会不知不觉地用到大量匿名内部类,如接受广播、点击事件、Handler消息处理等等。但是要注意,如果匿名内部类被异步线程使用,可能会引起内存泄漏。请看如下代码:
上述代码中,mRunnable 是非静态匿名内部类,会自动持有外部类SecondActivity3的引用,但是mRunnable被异步线程Thread使用,这样就会导致SecondActivity3在销毁的时候没法正常销毁,从而引起内存泄漏。
正确的做法应该是把mRunnable设置为静态的,这样就不会自动持有外部类SecondActivity3的引用,也就不会引起内存泄漏了。
五、注册/反注册未成对使用引起的内存泄漏
在andorid开发中,我们经常会在Activity的onCreate中注册广播接受器、EventBus等,如果忘记成对的使用反注册,可能会引起内存泄漏。开发过程中应该养成良好的相关,在onCreate或onResume中注册,要记得相应的在onDestroy或onPause中反注册。
六、资源对象没有关闭引起的内存泄漏
在android中,资源性对象比如Cursor、File、Bitmap、视频等,系统都用了一些缓冲技术,在使用这些资源的时候,如果我们确保自己不再使用这些资源了,要及时关闭,否则可能引起内存泄漏。因为有些操作不仅仅只是涉及到Dalvik虚拟机,还涉及到底层C/C++等的内存管理,不能完全寄希望虚拟机帮我们完成内存管理。
在这些资源不使用的时候,记得调用相应的类似close()、destroy()、recycler()、release()等函数,这些函数往往会通过jni调用底层C/C++的相应函数,完成相关的内存释放。
七、集合对象没有及时清理引起的内存泄漏
我们通常会把一些对象装入到集合中,当不使用的时候一定要记得及时清理集合,让相关对象不再被引用。如果集合是
static
、不断的往里面添加东西、又忘记去清理,肯定会引起内存泄漏。
使用 LeakCanary 检测 Android 的内存泄漏
内存泄漏防不胜防,通过LeakCanary工具,我们能在开发测试阶段发现绝大多数的内存泄漏。这个工具是开源的,使用也非常方便,而且能够相对准确定位出是哪里出现内存泄漏。
下面以AndroidStudio为例介绍LeakCanary的使用:
1
、在build.gradle中配置leakcanary的引用
compile 'com.squareup.leakcanary:leakcanary-android:1.4-beta2'
2
、使用RefWatcher监测本该被回收的对象。
LeakCanary.install()
会返回一个预定义的 RefWatcher,同时也会启用一个 ActivityRefWatcher,用于自动监控调用 Activity.onDestroy() 之后泄露的 activity。
在自己的Application中添加如下代码:
只需要上述两个步骤之后,LeakCanary就会自动监测内存泄漏,如果有内存泄漏在手机上面会提示,通知栏也会有通知,点击进去之后可以看到具体内存泄露的地方。debug的话,在控制台也会有相关的log输出。
总结:
1
、Handler持有的引用最好使用弱引用,在Activity被释放的时候要记得清空Message,取消Handler对象的Runnable;
2
、非静态内部类、非静态匿名内部类会自动持有外部类的引用,为避免内存泄露,可以考虑把内部类声明为静态的;
3
、对于生命周期比Activity长的对象,要避免直接引用Activity的context,可以考虑使用ApplicationContext;
4
、广播接收器、EventBus等的使用过程中,注册/反注册应该成对使用;
5
、不再使用的资源对象Cursor、File、Bitmap等要记住正确关闭;
6
、集合里面的东西、有加入就应该对应有相应的删除。
声明:
本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:
https://www.wpsshop.cn/w/我家自动化/article/detail/240229
推荐阅读
article
MT6737
Android
N 平台 Audio系统学习
----
Accdet
...
1、基本知识1.1、耳机插口种类耳机插口种类大概分为三段式和四段式。 三段式从左到右分为左声道、右声道、地。四段式从左到...
赞
踩
article
ADB
(
Android
Debug Bridge)详细
下载
安装及使用教程_
adb
(
android
d...
ADB
是每位
Android
开发者和测试人员的宝贵工具。掌握
ADB
的使用,可以极大提高开发和调试的效率。本教程旨在帮助您快...
赞
踩
article
mac
android
ndk
路径,(MAC)
Android
studio
3.5
NDK
环境配置...
1.第一步下载
ndk
,直接通过SDKManager下载
NDK
;2.配置环境变量;(1). pico .bash_prof...
赞
踩
article
Android
App Selinux
seapp
权限
详解_
android
添加
selinux
权限
...
system\sepolicy\privatekeys.conf[@TESTSEC]ALL:$DEFAULT_SYSTE...
赞
踩
article
Android
Jetpack
—
Navigation
组件:进行
应用程序
导航_
android
nav...
Navigation
组件是一种
Android
Jetpack
库,它可以帮助开发者轻松地实现
应用程序
中的导航功能。导...
赞
踩
article
Android
入门
基础
教程
(小白必看)
_
安卓
基础
教学...
在values文件下我们可以看到有strings.xml,里面可以添加定义的字符串。此时我们的test方法可以更改为这样...
赞
踩
article
2022 最新
Android
基础教程
,从
开发
入门到
项目
实战
【b站
动脑
学院
】学习笔记——第五章:中...
2022 最新
Android
基础教程
,从
开发
入门到
项目
实战
【b站
动脑
学院
】学习笔记——第五章:中级
控件
_androi...
赞
踩
article
android
bilibili
sd
卡,移动
bilibili
缓存
视频
到SD卡...
今天不知道网怎么了, 哔哩哔哩在电脑上看不了,在手机上倒是可以看, 手机屏幕又太小,我就打算把
视频
缓存
了,再拉到电脑上看...
赞
踩
article
android
免流
app,
bilibili
专属
免流
卡
手机版-
bilibili
专属
免流
卡
Appv5....
bilibili
专属
免流
卡
App是由
bilibili
官方联合中国联通推出的定制
专属
B站
免流
量卡,广大B站用户可以使用bi...
赞
踩
article
Android
setSystemUiVisibility
方法详解...
转载来源:https://blog.csdn.net/QQxiaoqiang1573/article/details/7...
赞
踩
article
android
+
手机
管家
,
腾讯
手机
管家
—
QQ
微信保护...
权限信息· com.tencent.qqpimsecure.permission.SAFE_ACCESS· 读取电池使用...
赞
踩
article
Android
--
快捷
方式
适配(二)_
android
判断是否有桌面
快捷
权限
...
前文
快捷
方式
适配(1)介绍了
快捷
方式
踩坑之资源文件索引混乱和系统版本适配两个方向遇到的问题及解决方案,这篇文章继续介绍踩...
赞
踩
article
android
4.3
用什么
微信
版本
,
安卓
4.3
系统
能用
微信
哪个
版本
...
大家好,我是时间财富网智能客服时间君,上述问题将由我为大家进行解答。
安卓
4.3
最高能装
微信
6.6.7可是登入会显示
版本
太...
赞
踩
article
android
4
.
4
.
2
和
4
.
4
.
4
,
Android
4
.
4
.
2
和
Android
4
.
4
.
4
不兼容An...
我们开发的视频应用,在其他手机上面都兼容,就是在华为
4
.
4
.
2
和华为
4
.
4
.
4
系统上面出现如下问题:java.lang....
赞
踩
article
Android
4.3 WIN7 64位系统 开发环境搭建
android
sdk
+
eclipse
...
一、下载 1. 下载安装SDK,百度搜索
android
sdk
即可,作者选择的
版本
是r22.3 2. 下载64位 ec...
赞
踩
article
Android
——
友盟
社会化
分享集成【
友盟
4.3版本
SDK
】_
social
club sdk...
前言:目前主流APP都会使用分享功能, 包括分享APP下载路径,分享APP里面有趣的东西,市面上分享集成
SDK
还是挺多的...
赞
踩
article
android
裁剪
apk
,
Android
4.3 系统
裁剪
——删除不使用的
app
及增加自己
app
...
Android
4.3 系统
裁剪
——删除不使用的
app
及增加自己
app
删除不使用的
apk
系统自带的
app
位置是在/and...
赞
踩
article
Android
4.3
新特性_安卓
4.3
支持
的
软件...
欢迎到
Android
4.3
版糖豆更甜!
Android
4.3
的
包括性能优化和强大
的
新功能,为用户和开发人员。本文档提供...
赞
踩
article
Android
4.3
是什么
版本
,
安卓
4.3
系统
能用
微信
哪个
版本
...
大家好,我是时间财富网智能客服时间君,上述问题将由我为大家进行解答。
安卓
4.3
最高能装
微信
6.6.7可是登入会显示
版本
太...
赞
踩
article
android
+
4.3
+
root
,
安卓
4.3
要怎么
root
?
安卓
4.3
root
教程...
安卓
4.3
已经发布,并在这几天陆续向Nexus设备推送。不少升级了
安卓
4.3
的朋友可能会问,
安卓
4.3
要怎么
root
?的...
赞
踩
相关标签
audio
android
adb
mac android ndk 路径
android jetpack
java
开发语言
学习
android studio
android bilibili sd卡
android 免流app
SystemUi
android+手机管家
android 4.3 用什么微信版本
android 4.4.2和4.4.4
社会化
友盟
android开发
android 裁剪 apk