`
LoveZhou
  • 浏览: 272391 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

Android 避免内存泄漏(译)

阅读更多
Android应用程序的内存被限定在16MB,至少在G1手机上是这样。对于一个手机来说,这已经占用了非常多的内存了,但是对于开发者想要实现的目标而言,这些内存是非常少的。即时你本来就没打算用掉所有的内存,但是你应该尽可能的少用内存,来让其他程序可以保持运行,而不是被系统杀掉。系统在内存里保存的应用程序越多,用户在应用程序之间选择切换的速度就会越快。作为我工作的一部分,我跟踪了Android应用程序内存泄露的情况,发现它们大多数是因为同一个问题:保持了对Context对象的长期的引用。

在Android系统上,很多操作都用到了Context对象,但是大多数都是用来加载和访问资源的。这就是为什么所有的显示控件都需要一个Context对象作为构造方法的参数。在Android应用程序中,你通常可以使用两种Context对象,Activity和Application。当类或者方法需要Context对象的时候,开发者通常会用第一个作为参数。
@Override
protected void onCreate(Bundle state) {
  super.onCreate(state);
 
  TextView label = new TextView(this);
  label.setText("Leaks are bad");
 
  setContentView(label);
}
这就意味着,View对象对整个activity保持引用,因此,也就保持对activity内的所有东西的引用;通常是整个View结构和它所有的资源。所以,如果你一直保持着对Activity的引用,你占用了很多内存。在你不注意的时候,你很容易就持有对activity的长期引用。
当屏幕方向改变时,默认的,系统会摧毁当前的activity,然后创建一个新的activity,这个新的activity会显示刚才的状态。在这样做的过程中,Android系统会重新加载UI用到的资源。现在假设你的应用程序中有一个比较大的bitmap类型的图片,然而你不想每次旋转时都重新加载它。
保持屏幕旋转,又不让它重新加载,最简单的方法是用静态变量的方法。
private static Drawable sBackground;
 
@Override
protected void onCreate(Bundle state) {
  super.onCreate(state);
 
  TextView label = new TextView(this);
  label.setText("Leaks are bad");
 
  if (sBackground == null) {
    sBackground = getDrawable(R.drawable.large_bitmap);
  }
  label.setBackgroundDrawable(sBackground);
 
  setContentView(label);
}
这样的代码执行起来是快速的,但是是错误的;这样写会一直保持着对activity的引用。当一个Drawable对象附属于一个View时,这个View就相当于drawable对象的一个回调(引用)。在上面的代码片段中,就意味着drawable和TextView存在着引用的关系,而TextView自己引用着activity(Context对象),这个activity又引用着相当多的东西。
这个例子就是非常简单的泄露Context对象的一种情况,你可以在“ Home screen's source code( unbindDrawables()方法)”中看到是如何做的,当activity被摧毁时,设置drawable的回调(引用)为null。令人感兴趣的是,有很多种情况,你会创建出一个泄露context对象的链,它们是糟糕的。它们会很快耗光内存,使你的内存溢出。

有两种简单的方法可以避免由引用context对象造成的内存泄露。最明显的一个方法是,避免context对象超出它的作用范围。上面的例子显展示了静态引用的情况,但是在类的内部,隐式的引用外部的类同样的危险。第二种方法是,使用Application对象。这个context对象会随着应用程序的存在而存在,而不依赖于activity的生命周期。如果你打算对context对象保持一个长期的引用,请记住这个application对象。通过调用Context.getApplicationContext() 或者 Activity.getApplication().方法,你可以很容易的得到这个对象。

总之,要避免由于引用context对象造成的内存泄露,记住以下几点:

不要保持对activity的持久引用(对activity的引用应该和activity本身有相同的生命周期)
尽量使用application代替activity
如果不能控制非静态的内部类的生命周期,尽量在activity中避免有非静态的内部类,在activity中使用静态的类,要对activity保持弱引用。
垃圾回收器并不能保证阻止内存泄露
分享到:
评论

相关推荐

    Android webview 内存泄露的解决方法

    Android webview 内存泄露的解决方法 最近在activity嵌套webview显示大量图文发现APP内存一直在涨,没法释放内存,查了很多资料,大概是webview的一...这样动态生成webview就能避免内存泄漏,可是这样会导致部分机型的w

    Android处理内存泄漏的代码例子

    本示例代码着重展示了如何避免Android应用中的内存泄漏,主要包括五个关键方面:关闭游标、重用适配器、回收图像、注销监听器以及释放引用。下面将详细解释这些方法。 1. 关闭游标: 在Android数据库操作中,游标是...

    Android Native 内存泄漏系统化解决方案

    Android Native 内存泄漏系统化解决方案 在 Android 平台上,C++ 内存泄漏问题的分析和定位一直是困扰开发人员的难题,因为地图渲染、导航等核心功能对性能要求很高,高德地图 APP 中存在大量的 C++ 代码。解决这个...

    使用Android Studio检测内存泄露(LeakCanary)

    内存泄露在Android开发中是一个非常重要的问题,因为它可能导致应用程序运行缓慢、消耗过多资源甚至崩溃。Android Studio提供了多种工具帮助开发者检测和解决内存泄露,其中包括Memory Profiler和LeakCanary。 ...

    androidStudio内存泄漏分析

    在Android应用开发中,内存泄漏是一个严重的问题,它可能导致应用性能下降、响应变慢甚至崩溃。Android Studio作为官方推荐的集成开发环境(IDE),提供了强大的内存泄漏检测工具,帮助开发者定位并解决这些问题。...

    Android内存泄漏简介

    总之,虽然Java的垃圾回收机制为内存管理提供了一定的便利,但Android应用开发者仍然需要注意正确管理内存,以避免内存泄漏的发生。通过学习和实践上述知识点,开发者可以提高编写高效且稳定的应用程序的能力。

    Android避免内存泄露

    如何高效避免Android内存泄露,文档时根据我多年的Android经验编写而成,希望对您有所帮助。

    Android应用程序如何避免内存泄漏

    以下是避免Android内存泄漏的一些关键点和检查泄漏原因的方法。 首先,理解Android内存管理的基本原则至关重要。每个Android应用运行在一个独立的Linux进程中,当应用退出时,其分配的内存会随之释放。然而,如果...

    Android App定位和规避内存泄露方法研究

    为了避免内存泄露,本文将详细介绍如何检测、定位以及规避内存泄露的方法。 首先,了解内存泄露的基本概念和Android内存管理模型是很有必要的。Android应用的内存主要分为几种类型:Virtual Set Size (VSS),表示...

    android系统分析内存泄露测试

    在Android系统中,内存泄漏是一个严重的问题,它会导致应用程序占用过多的内存,进而影响设备性能,甚至可能导致应用崩溃。...只有这样,才能确保应用在运行时能够有效地利用内存,避免因内存泄漏导致的问题。

    android内存泄露测试

    - **ProGuard**:一个代码混淆和优化工具,也可以用来检查内存泄漏,尤其是在代码混淆后。 #### 二、MAT的安装与使用 1. **安装MAT**: - 打开Eclipse,选择`Help -> Install New Software...` - 在`Work with:`...

    AndroidApp定位和规避内存泄露方法研究

    在Android应用开发中,内存管理是一项至关重要的...在Android开发过程中,掌握以上知识并付诸实践,能够有效避免内存泄露问题,提升应用的性能和稳定性。持续学习和优化内存管理策略,是每个Android开发者必备的技能。

    android性能优化之内存泄露

    ### Android性能优化之内存泄露 #### 一、内存泄露概述 在Android开发中,内存管理是确保应用程序稳定性和性能的关键因素之一。不当的内存管理可能导致内存泄露,进而引发一系列问题,如应用程序运行缓慢、崩溃...

    Node.js-Androidnative层代码内存泄漏问题调试利器

    在Android应用开发中,尤其是涉及到Native层代码时,内存泄漏是一个...通过利用Node.js和LeakTracer这样的工具,开发者可以在Native层代码的内存管理上达到更高的精度,避免因内存泄漏导致的问题,从而提升用户体验。

    Android应用程序内存泄漏的分析.pdf

    标题中提到的是关于“Android应用程序内存泄漏的分析”,这意味着文档的核心内容将集中在分析...理解和掌握这些知识点对Android开发人员来说是非常重要的,它可以帮助他们在日常开发中有效地避免和解决内存泄漏问题。

    android应用内存监控工具

    1. 避免内存泄漏:长期占用但不再使用的内存会导致内存泄漏,消耗设备资源,甚至导致应用崩溃。 2. 提升性能:优化内存使用可以减少应用启动时间,提高运行速度。 3. 延长电池寿命:减少不必要的内存消耗,有助于...

    android内存泄露的检测和排查

    在Android开发中,内存泄漏是一个严重的问题,它会导致应用程序占用过多的内存,影响性能,甚至导致应用崩溃。本文将深入探讨Android内存泄漏的检测和排查方法,并通过一个锁屏内存泄漏的例子进行具体分析。 首先,...

    Android mvp简单模型搭建及其防内存泄漏解决办法

    在MVP模式下,我们需要注意以下几点来避免内存泄漏: 1. **弱引用**:Presenter不应强持有View的引用,因为这可能导致Activity或Fragment无法正常回收。使用WeakReference或Android的LocalBroadcastManager可以避免...

    android应用内存泄露

    通过正确地使用`procrank`工具进行检测以及MAT等专业工具进行定位,可以有效地避免和解决内存泄露问题,从而提升应用的性能和稳定性。此外,不断学习和实践相关的工具和技术也是提高自身解决问题能力的重要途径。

    【android】android之内存泄漏

    本文将详细介绍内存泄漏的概念、产生的原因、以及如何避免内存泄漏,帮助开发者更好地理解内存泄漏,并采取有效的措施来解决这一问题。 #### 二、基础知识回顾 ##### 2.1 JVM/ART Java程序运行在一个虚拟环境之中...

Global site tag (gtag.js) - Google Analytics