Android常见内存泄露,学会这六招优化APP性能
很多开发者都知道,在面试的时候会经常被问到内存泄露和内存溢出的问题。
1.内存溢出(Out Of Memory,简称 OOM),通俗理解就是内存不够,即内存占用超出内存的空间大小。
2.内存泄漏(Memory Leak),简单理解就是内存使用完毕之后本该垃圾回收却未被回收。
- 2
在正式了解内存泄露之前,首先来简单回顾一下 Java 内存分配策略。
Java 程序运行时的内存分配策略有三种,分别是静态分配、栈式分配、堆式分配,对应的主要内存空间分别是静态存储区(也称方法区)、栈区、堆区。
1.静态存储区(方法区)
主要存放静态数据、全局 static 数据和常量。这块内存在程序编译时就已经分配好,并且在程序整个运行期间都存在。
2.栈区
当方法被执行时,方法体内的局部变量都在栈上创建,并在方法执行结束时这些局部变量所持有的内存将会自动被释放。因为栈内存分配运算内置于处理器的指令集中,效率很高,但是分配的内存容量有限。
3.堆区
又称动态内存分配,通常就是指在程序运行时直接 new 出来的内存。这部分内存在不使用时将会由 Java 垃圾回收器来负责回收。
- 3
在 Java 中,内存的分配是由程序完成的,而内存的释放是由 GC 完成的,这种方式大大简化了程序员的工作,但同时却加重了 JVM 的工作,这也是 Java 程序运行速度较慢的原因之一。GC 为了能够正确释放对象,必须监控每一个对象的运行状态,包括对象的申请、引用、被引用、赋值等,监视对象的状态是为了更加准确地、及时地释放对象,而释放对象的根本原则就是该对象不再被引用。
END
内存泄露
- 1
Java 有了垃圾回收功能,程序员无需手动管理内存分配,减少了段错误导致的闪退,也减少了内存泄漏导致的堆空间膨胀,让编写的代码更加安全。但是 Java 中依然有可能发生内存泄露,而 Android 主要使用 Java 作为开发语言,在开发过程中很可能一个很小的错误都会引起内存的泄露。有内存泄露存在时,APP 就会浪费大量的内存,就会由于内存不够而频繁进行垃圾回收,大家知道垃圾回收是非常耗时的操作,这样就会导致 APP 的严重卡顿。在最坏的时候,甚至由于内存耗尽导致OutOfMemery,最终程序异常退出。
- 2
内存泄露是一个令很多开发者头疼的问题,那么我们今天就来学习一下 Activity 有关的内存泄露问题。
在 Android 中,泄露 Context 对象的问题尤其严重,特别像 Activity 这样的 Context 对象会引用大量很占用内存的对象,如果 Context 对象发生了内存泄漏,那它所引用的所有对象都被泄漏了。Activity 是非常重量级的对象,所以我们应该极力避免妨碍系统对其进行回收,然而实际情况是有多种方式会无意间就泄露了Activity 对象。
END
Activity 六招优化性能秘籍
- 1
1. 静态变量造成的内存泄漏
最简单的泄漏 Activity 就是在 Activity 类中定义一个 static 变量,并将其指向一个运行中的 Activity 实例。如果在 Activity 的生命周期结束之前,没有清除这个引用,那它就会泄漏。由于 Activity 的类对象是静态的,一旦加载,就会在 APP 运行时一直常驻内存,如果类对象不卸载,其静态成员就不会被垃圾回收。
- 2
2. 单例造成的内存泄漏
另一种类似的情况是对经常启动的 Activity 实现一个单例模式,让其常驻内存可以使它能够快速恢复状态。
如我们有一个创建起来非常耗时的 View,在同一个 Activity 不同的生命周期中都保持不变呢,就为它实现一个单例模式。一旦 View 被加载到界面中,它就会持有 Context 的强引用,也就是我们的 Activity 对象。
由于我们是通过一个静态成员引用了这个 View,所以我们也就引用了 Activity,因此 Activity 就发生了泄漏。所以一定不要把加载的 View 赋值给静态变量,如果你真的需要,那一定要确保在 Activity 销毁之前将其从 View 层级中移除。
- 3
3. 内部类造成的内存泄漏
我们经常在 Activity 内部定义一个内部类,这样做可以增加封装性和可读性。但是如果当我们创建了一个内部类的对象,并通过静态变量持有了 Activity 的引用,那也会可能发生 Activity 泄漏。
- 4
4. 线程造成的内存泄漏
在 Activity 内定义了一个匿名的 AsyncTask 对象,就有可能发生内存泄漏。如果 Activity 被销毁之后 AsyncTask 仍然在执行,那就会阻止垃圾回收器回收Activity 对象,进而导致内存泄漏,直到执行结束才能回收 Activity。
同样的,使用 Thread 和 TimerTask 也可能导致 Activity 泄漏。只要它们是通过匿名类创建的,尽管它们在单独的线程被执行,它们也会持有对 Activity 的强引用,进而导致内存泄漏。
- 5
5.Handler 造成的内存泄漏
定义一个匿名的 Runnable 对象并将其提交到 Handler 上也可能导致 Activity 泄漏。Runnable 对象间接地引用了定义它的 Activity 对象,而它会被提交到Handler 的 MessageQueue 中,如果它在 Activity 销毁时还没有被处理,就会导致 Activity 泄漏。
- 6
6. 资源未关闭造成的内存泄漏
如系统服务可以通过 context.getSystemService 获取,它们负责执行某些后台任务,或者为硬件访问提供接口。如果 Context 对象想要在服务内部的事件发生时被通知,那就需要把自己注册到服务的监听器中。然而,这会让服务持有 Activity 的引用,如果开发者忘记在 Activity 销毁时取消注册,也会导致 Activity泄漏。
END
总结
- 1
这里只是简单的分析了常见的有关 Activity 导致的内存泄露,其实导致内存泄露的地方还有很多,但是基本原理都一样。由于篇幅原因,这里不做过多介绍,以后再逐渐进行分析和学习。
虽然现在手机内存越来越大,内存泄露不会像以前由于内存过小造成 OOM。但是过量的内存泄露依然会造成内存溢出,影响用户体验,所以解决好内存泄露的问题非常重要。
Android常见内存泄露,学会这六招优化APP性能的更多相关文章
- Android 常见内存泄露 & 解决方案
前言 内存泄漏(Memory Leak)是指程序中己动态分配的堆内存由于某种原因程序未释放或无法释放,造成系统内存的浪费,导致程序运行速度减慢甚至系统崩溃 (OOM) 等严重后果. 那什么情况下不能被 ...
- Android常见内存泄露
前言 对于内存泄漏,我想大家在开发中肯定都遇到过,只不过内存泄漏对我们来说并不是可见的,因为它是在堆中活动,而要想检测程序中是否有内存泄漏的产生,通常我们可以借助LeakCanary.MAT等工具来检 ...
- android 常见内存泄漏原因及解决办法
android常见内存泄漏主要有以下几类: 一.Handler 引起的内存泄漏. 在Android开发中,我们经常会使用Handler来控制主线程UI程序的界面变化,使用非常简单方便,但是稍不注意,很 ...
- Android 的内存泄露和内存限制
转载自 https://blog.csdn.net/goodlixueyong/article/details/40716779 https://blog.csdn.net/vshuang/artic ...
- Android 防内存泄露handler
Android 防内存泄露handler 1.使用弱引用 WeakRefHander /** * 作者: allen on 15/11/24.感谢开源作者https://coding.net/u/co ...
- 关于Android 的内存泄露及分析
一. Android的内存机制Android的程序由Java语言编写,所以Android的内存管理与Java的内存管理相似.程序员通过new为对象分配内存,所有对象在java堆内分配空间:然而对象的释 ...
- 【转】.. Android应用内存泄露分析、改善经验总结
原文网址:http://wetest.qq.com/lab/view/107.html?from=ads_test2_qqtips&sessionUserType=BFT.PARAMS.194 ...
- Android之内存泄露、内存溢出、内存抖动分析
内存 JAVA是在JVM所虚拟出的内存环境中运行的,内存分为三个区:堆.栈和方法区.栈(stack):是简单的数据结构,程序运行时系统自动分配,使用完毕后自动释放.优点:速度快.堆(heap) ...
- Android中内存泄露与如何有效避免OOM总结
一.关于OOM与内存泄露的概念 我们在Android开发过程中经常会遇到OOM的错误,这是因为我们在APP中没有考虑dalvik虚拟机内存消耗的问题. 1.什么是OOM OOM:即OutOfMemoe ...
随机推荐
- adobe flash player 下载地址
1. https://www.adobe.com/cn/products/flashplayer/distribution3.html
- 分享知识-快乐自己:Java常用API总结
1):java.io.BufferedReader类(用于从文件中读入一段字符:所属套件:java.io) 1. 构造函数BufferedReader(java.io.FileReader FileR ...
- freeMarker(九)——程序开发指南补充知识
学习笔记,选自freeMarker中文文档,译自 Email: ddekany at users.sourceforge.net 1.变量.范围 本章介绍当模板在访问变量时发生了什么事情,还有变量是如 ...
- ONVIF Device Manager v2.2.146
对接ONVIF使用软件,用于对接支持onvif协议的IPC厂家设置 http://download.csdn.net/detail/li_dabo/9761415
- luogu1833 樱花
背包问题小合集 01背包 完全背包 多重背包混着来 对于01背包:把它想象成最大物品数为1的多重背包 对于完全背包:把它想象成最大物品数为m/w[i]的多重背包 对于多重背包:把它想象成...等等这本 ...
- 影响Cache的几个HTTP头信息【转载http://hi.baidu.com/feilala_fly/item/f79eca08fbf389026c9048a7】
Http的Cache机制总共有4个组成部分: Cache-Control.Last-Modified(If-Modified-Since).Etag(If-None-Match) .Expires 服 ...
- P1330 封锁阳光大学(二分图染色)
题目描述 曹是一只爱刷街的老曹,暑假期间,他每天都欢快地在阳光大学的校园里刷街.河蟹看到欢快的曹,感到不爽.河蟹决定封锁阳光大学,不让曹刷街. 阳光大学的校园是一张由N个点构成的无向图,N个点之间由M ...
- 洛谷P4721 【模板】分治 FFT(生成函数+多项式求逆)
传送门 我是用多项式求逆做的因为分治FFT看不懂…… upd:分治FFT的看这里 话说这个万恶的生成函数到底是什么东西…… 我们令$F(x)=\sum_{i=0}^\infty f_ix^i,G(x) ...
- 洛谷【P2115】[USACO14MAR]破坏Sabotage
我对二分的理解:https://www.cnblogs.com/AKMer/p/9737477.html 题目传送门:https://www.luogu.org/problemnew/show/P21 ...
- bzoj 2096 [POI2004]ZAW——二进制枚举
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=2069 可以把直接相连的点分成 从1点出的一部分 和 走向1点的一部分.多起点最短路就和 ...