1. 很多开发者都知道,在面试的时候会经常被问到内存泄露和内存溢出的问题。

    1.内存溢出(Out Of Memory,简称 OOM),通俗理解就是内存不够,即内存占用超出内存的空间大小。

    2.内存泄漏(Memory Leak),简单理解就是内存使用完毕之后本该垃圾回收却未被回收。

  2. 2

    在正式了解内存泄露之前,首先来简单回顾一下 Java 内存分配策略。

    Java 程序运行时的内存分配策略有三种,分别是静态分配、栈式分配、堆式分配,对应的主要内存空间分别是静态存储区(也称方法区)、栈区、堆区。

    1.静态存储区(方法区)

    主要存放静态数据、全局 static 数据和常量。这块内存在程序编译时就已经分配好,并且在程序整个运行期间都存在。

    2.栈区

    当方法被执行时,方法体内的局部变量都在栈上创建,并在方法执行结束时这些局部变量所持有的内存将会自动被释放。因为栈内存分配运算内置于处理器的指令集中,效率很高,但是分配的内存容量有限。

    3.堆区

    又称动态内存分配,通常就是指在程序运行时直接 new 出来的内存。这部分内存在不使用时将会由 Java 垃圾回收器来负责回收。

  3. 3

    在 Java 中,内存的分配是由程序完成的,而内存的释放是由 GC 完成的,这种方式大大简化了程序员的工作,但同时却加重了 JVM 的工作,这也是 Java 程序运行速度较慢的原因之一。GC 为了能够正确释放对象,必须监控每一个对象的运行状态,包括对象的申请、引用、被引用、赋值等,监视对象的状态是为了更加准确地、及时地释放对象,而释放对象的根本原则就是该对象不再被引用。

    END

内存泄露

 
  1. 1

    Java 有了垃圾回收功能,程序员无需手动管理内存分配,减少了段错误导致的闪退,也减少了内存泄漏导致的堆空间膨胀,让编写的代码更加安全。但是 Java 中依然有可能发生内存泄露,而 Android 主要使用 Java 作为开发语言,在开发过程中很可能一个很小的错误都会引起内存的泄露。有内存泄露存在时,APP 就会浪费大量的内存,就会由于内存不够而频繁进行垃圾回收,大家知道垃圾回收是非常耗时的操作,这样就会导致 APP 的严重卡顿。在最坏的时候,甚至由于内存耗尽导致OutOfMemery,最终程序异常退出。

  2. 2

    内存泄露是一个令很多开发者头疼的问题,那么我们今天就来学习一下 Activity 有关的内存泄露问题。

    在 Android 中,泄露 Context 对象的问题尤其严重,特别像 Activity 这样的 Context 对象会引用大量很占用内存的对象,如果 Context 对象发生了内存泄漏,那它所引用的所有对象都被泄漏了。Activity 是非常重量级的对象,所以我们应该极力避免妨碍系统对其进行回收,然而实际情况是有多种方式会无意间就泄露了Activity 对象。

    END

Activity 六招优化性能秘籍

 
  1. 1

    1. 静态变量造成的内存泄漏

    最简单的泄漏 Activity 就是在 Activity 类中定义一个 static 变量,并将其指向一个运行中的 Activity 实例。如果在 Activity 的生命周期结束之前,没有清除这个引用,那它就会泄漏。由于 Activity 的类对象是静态的,一旦加载,就会在 APP 运行时一直常驻内存,如果类对象不卸载,其静态成员就不会被垃圾回收。

  2. 2

    2. 单例造成的内存泄漏

    另一种类似的情况是对经常启动的 Activity 实现一个单例模式,让其常驻内存可以使它能够快速恢复状态。

    如我们有一个创建起来非常耗时的 View,在同一个 Activity 不同的生命周期中都保持不变呢,就为它实现一个单例模式。一旦 View 被加载到界面中,它就会持有 Context 的强引用,也就是我们的 Activity 对象。

    由于我们是通过一个静态成员引用了这个 View,所以我们也就引用了 Activity,因此 Activity 就发生了泄漏。所以一定不要把加载的 View 赋值给静态变量,如果你真的需要,那一定要确保在 Activity 销毁之前将其从 View 层级中移除。

  3. 3

    3. 内部类造成的内存泄漏

    我们经常在 Activity 内部定义一个内部类,这样做可以增加封装性和可读性。但是如果当我们创建了一个内部类的对象,并通过静态变量持有了 Activity 的引用,那也会可能发生 Activity 泄漏。

  4. 4

    4. 线程造成的内存泄漏

    在 Activity 内定义了一个匿名的 AsyncTask 对象,就有可能发生内存泄漏。如果 Activity 被销毁之后 AsyncTask 仍然在执行,那就会阻止垃圾回收器回收Activity 对象,进而导致内存泄漏,直到执行结束才能回收 Activity。

    同样的,使用 Thread 和 TimerTask 也可能导致 Activity 泄漏。只要它们是通过匿名类创建的,尽管它们在单独的线程被执行,它们也会持有对 Activity 的强引用,进而导致内存泄漏。

  5. 5

    5.Handler 造成的内存泄漏

    定义一个匿名的 Runnable 对象并将其提交到 Handler 上也可能导致 Activity 泄漏。Runnable 对象间接地引用了定义它的 Activity 对象,而它会被提交到Handler 的 MessageQueue 中,如果它在 Activity 销毁时还没有被处理,就会导致 Activity 泄漏。

  6. 6

    6. 资源未关闭造成的内存泄漏

    如系统服务可以通过 context.getSystemService 获取,它们负责执行某些后台任务,或者为硬件访问提供接口。如果 Context 对象想要在服务内部的事件发生时被通知,那就需要把自己注册到服务的监听器中。然而,这会让服务持有 Activity 的引用,如果开发者忘记在 Activity 销毁时取消注册,也会导致 Activity泄漏。

    END

总结

 
  1. 1

    这里只是简单的分析了常见的有关 Activity 导致的内存泄露,其实导致内存泄露的地方还有很多,但是基本原理都一样。由于篇幅原因,这里不做过多介绍,以后再逐渐进行分析和学习。

    虽然现在手机内存越来越大,内存泄露不会像以前由于内存过小造成 OOM。但是过量的内存泄露依然会造成内存溢出,影响用户体验,所以解决好内存泄露的问题非常重要。

Android常见内存泄露,学会这六招优化APP性能的更多相关文章

  1. Android 常见内存泄露 & 解决方案

    前言 内存泄漏(Memory Leak)是指程序中己动态分配的堆内存由于某种原因程序未释放或无法释放,造成系统内存的浪费,导致程序运行速度减慢甚至系统崩溃 (OOM) 等严重后果. 那什么情况下不能被 ...

  2. Android常见内存泄露

    前言 对于内存泄漏,我想大家在开发中肯定都遇到过,只不过内存泄漏对我们来说并不是可见的,因为它是在堆中活动,而要想检测程序中是否有内存泄漏的产生,通常我们可以借助LeakCanary.MAT等工具来检 ...

  3. android 常见内存泄漏原因及解决办法

    android常见内存泄漏主要有以下几类: 一.Handler 引起的内存泄漏. 在Android开发中,我们经常会使用Handler来控制主线程UI程序的界面变化,使用非常简单方便,但是稍不注意,很 ...

  4. Android 的内存泄露和内存限制

    转载自 https://blog.csdn.net/goodlixueyong/article/details/40716779 https://blog.csdn.net/vshuang/artic ...

  5. Android 防内存泄露handler

    Android 防内存泄露handler 1.使用弱引用 WeakRefHander /** * 作者: allen on 15/11/24.感谢开源作者https://coding.net/u/co ...

  6. 关于Android 的内存泄露及分析

    一. Android的内存机制Android的程序由Java语言编写,所以Android的内存管理与Java的内存管理相似.程序员通过new为对象分配内存,所有对象在java堆内分配空间:然而对象的释 ...

  7. 【转】.. Android应用内存泄露分析、改善经验总结

    原文网址:http://wetest.qq.com/lab/view/107.html?from=ads_test2_qqtips&sessionUserType=BFT.PARAMS.194 ...

  8. Android之内存泄露、内存溢出、内存抖动分析

      内存   JAVA是在JVM所虚拟出的内存环境中运行的,内存分为三个区:堆.栈和方法区.栈(stack):是简单的数据结构,程序运行时系统自动分配,使用完毕后自动释放.优点:速度快.堆(heap) ...

  9. Android中内存泄露与如何有效避免OOM总结

    一.关于OOM与内存泄露的概念 我们在Android开发过程中经常会遇到OOM的错误,这是因为我们在APP中没有考虑dalvik虚拟机内存消耗的问题. 1.什么是OOM OOM:即OutOfMemoe ...

随机推荐

  1. 使用ksar解析sar监控日志

    sar 是属于sysstat包中的一个工具 安装sysstat包后,默认创建一个/etc/cron.d/sysstat文件,其默认内容为: # run system activity accounti ...

  2. Android平台及其架构(部分转载)

    一.Android的系统架构 1.      应用程序 同Android系统一起发布的核心应用程序,如email 客户端,SMS 短消息程序,日历,地图,浏览器,联系人管理程序等. 这些应用程序都是用 ...

  3. 什么是shell【TLCL】

    常用命令 date cal df——report file system disk space usage free——display amount of free and used memory i ...

  4. java原生数据类型和引用类型

    java 中String 是个对象,是引用类型基础类型与引用类型的区别是,基础类型只表示简单的字符或数字,引用类型可以是任何复杂的数据结构基本类型仅表示简单的数据类型,引用类型可以表示复杂的数据类型, ...

  5. Python基础-数据写入execl

    import xlwt book = xlwt.Workbook()#创建一个excel sheet = book.add_sheet('lanxia')#添加一个sheet页 title = ['姓 ...

  6. Python--基础文件读写操作

    1,open(),对文件进行读写操作之前,要先打开文件,获取文件的句柄: 懒人专用方法,文件打开后不用关闭 with open(r'somefile.txt','r+',encoding='utf8' ...

  7. linux命令学习笔记(1):ls命令

    ls命令是linux下最常用的命令.ls命令就是list的缩写缺省下ls用来打印出当前目录的清单 如果ls指定其他目录那么就会显示指定目录里的文件及文件夹清单. 通过ls 命令不仅可以查 看li ...

  8. OpenCV——饱和度调整

    参考: 闲人阿发伯的博客 // define head function #ifndef PS_ALGORITHM_H_INCLUDED #define PS_ALGORITHM_H_INCLUDED ...

  9. android:layout_weight的真实含义/android:layout_gravity的条件

    用layout_weight的时候,不要把宽度(或是高度,你想分配weight的那个)设成match_parent. android:layout_weight只适用于LinearLayout and ...

  10. 1022 Digital Library (30)(30 分)

    A Digital Library contains millions of books, stored according to their titles, authors, key words o ...