android内存优化

简介: Android的应用被限制为最多占用16m的内存,至少在T-Mobile G1上是这样的(当然现在已经有几百兆的内存可以用了——译者注)。它包括电话本身占用的和开发者可以使用的两部分。即使你没有占用全部内存的打算,你也应该尽量少的使用内存,以免别的应用在运行的时候关闭你的应用。Android能在内存中保持的应用越多,用户在切换应用的时候就越快。作为我的一项工作,我仔细研究了Android应
Android的应用被限制为最多占用16m的内存,至少在T-Mobile G1上是这样的(当然现在已经有几百兆的内存可以用了——译者注)。它包括电话本身占用的和开发者可以使用的两部分。即使你没有占用全部内存的打算,你也应该尽量少的使用内存,以免别的应用在运行的时候关闭你的应用。Android能在内存中保持的应用越多,用户在切换应用的时候就越快。作为我的一项工作,我仔细研究了Android应用的内存泄露问题,大多数情况下它们是由同一个错误引起的,那就是对一个上下文(Context)保持了长时间的引用。

    在Android中,上下文(Context)被用作很多操作中,但是大部分是载入和访问资源。这就是所有的widget都会在它们的构造函数中接受一个上下文(Context)参数。在一个合格的Android应用中,你通常能够用到两种上下文(Context):活动(Activity)和应用(Application)。活动(Activity)通常被传递给需要上下文(Context)参数的类或者方法:


  1. @Override  
  2. protected void onCreate(Bundle state) {  
  3.   super.onCreate(state);  
  4.    
  5.   TextView label = new TextView(this);  
  6.   label.setText("Leaks are bad");  
  7.    
  8.   setContentView(label);  
  9. }  


    这就意味着那个View有一个对整个活动(Activity)的引用并且对这个活动(Activity)中保持的所有对象有保持了引用;通常它们包括整个View的层次和它的所有资源。因此,如果你“泄露”了上下文(Context)(这里“泄露”的意思是你保持了一个引用并且组织GC收集它),你将造成大量的内存泄露。如果你不够小心的话,“泄露”一整个活动(Activity)是件非常简单的事情。

    当屏幕的方向改变时系统会默认的销毁当前的活动(Activity)并且创建一个新的并且保持了它的状态。这样的结果就是Android会从资源中重新载入应用的UI。现在想象一下,你写了一个应用,有一个非常大的位图,并且你并不想在每次旋转时都重新载入。保留它并且每次旋转不重新加载的最简单的办法就是把它保存在一个静态字段上:

  1. private static Drawable sBackground;  
  2.    
  3. @Override  
  4. protected void onCreate(Bundle state) {  
  5.   super.onCreate(state);  
  6.    
  7.   TextView label = new TextView(this);  
  8.   label.setText("Leaks are bad");  
  9.    
  10.   if (sBackground == null) {  
  11.     sBackground = getDrawable(R.drawable.large_bitmap);  
  12.   }  
  13.   label.setBackgroundDrawable(sBackground);  
  14.    
  15.   setContentView(label);  
  16. }  



    这段代码非常快,同时也错的够离谱。它泄露了当第一次屏幕角度改变时创建的第一个活动(Activity)。当一个Drawable被附加到一个View,这个View被设置为drawable的一个回调。在上面的代码片断中,这意味着这个Drawable对TextView有一个引用,同时这个TextView对Activity(Context对象)保持着引用,同时这个Activity对很多对象又有引用(这个多少还要看你的代码了)。

    这个例子是造成Context泄露的最简单的一个原因,你可以看一下我们在主屏幕源码(查看unbindDrawables()方法)中是通过在Activity销毁时设置保存过的Drawable的回调为空来解决这个问题的。更为有趣的是,你可以创建一个context泄露的链,当然这非常的糟糕。它们可以让你飞快的用光所有的内存。

    有两种简单的方法可以避免与context相关的内存泄露。最明显的一个就是避免在context的自身的范围外使用它。上面的例子展示了在类内部的一个静态的引用和它们对外部类的间接引用是非常危险的。第二个解决方案就是使用Application Context。这个context会伴随你的应用而存在,并且不依赖Activity的的生命周期。如果你计划保持一个需要context的长生命周期的对象,请记得考虑Application对象。你可以非常方便的通过调用Context.getApplicationContext() 或者 Activity.getApplication()获取它。

总之,为了避免涉及到context的内存泄露,请记住如下几点:

  1. 不要对一个Activity Context保持长生命周期的引用(一个对Activity的引用应该与Activity自身的生命周期相同)
  2. 尝试使用应用上下文(context-application)代替活动上下文(context-activity)
  3. 如果你不能控制它们的生命周期,在活动(Activity)中避免使用不是静态的内部类,使用静态类并且使用弱引用到活动(Activity)的内部。对于这个问题的解决方法是使用静态的内部类与一个弱引用(WeakReference)的外部类。就像ViewRoot和它的W内部类那么实现的。
  4. 垃圾回收器对于内存泄露来说并不是百分百保险的。
目录
相关文章
|
8月前
|
缓存 编解码 Android开发
Android内存优化之图片优化
本文主要探讨Android开发中的图片优化问题,包括图片优化的重要性、OOM错误的成因及解决方法、Android支持的图片格式及其特点。同时介绍了图片储存优化的三种方式:尺寸优化、质量压缩和内存重用,并详细讲解了相关的实现方法与属性。此外,还分析了图片加载优化策略,如异步加载、缓存机制、懒加载等,并结合多级缓存流程提升性能。最后对比了几大主流图片加载框架(Universal ImageLoader、Picasso、Glide、Fresco)的特点与适用场景,重点推荐Fresco在处理大图、动图时的优异表现。这些内容为开发者提供了全面的图片优化解决方案。
323 1
|
存储 前端开发 Java
Android MVVM架构模式下如何避免内存泄漏
Android采用MVVM架构开发项目,如何避免内存泄漏风险?怎样避免内存泄漏?
411 1
|
存储 开发工具 Android开发
构建高效的Android应用:从内存管理到用户界面
【5月更文挑战第29天】 随着智能手机的普及,Android应用的开发变得日益重要。然而,许多开发者在开发过程中忽视了性能优化,导致应用运行缓慢,用户体验差。本文将深入探讨如何通过有效的内存管理和用户界面优化,提升Android应用的性能。我们将详细介绍内存泄漏的原因和解决方案,以及如何使用Android的新特性来创建流畅的用户界面。无论你是新手还是经验丰富的开发者,都可以从本文中获得有用的技巧和建议。
|
监控 Java Android开发
深入探讨Android系统的内存管理机制
本文将深入分析Android系统的内存管理机制,包括其内存分配、回收策略以及常见的内存泄漏问题。通过对这些方面的详细讨论,读者可以更好地理解Android系统如何高效地管理内存资源,从而提高应用程序的性能和稳定性。
559 16
|
监控 Java Android开发
深入探索Android系统的内存管理机制
本文旨在全面解析Android系统的内存管理机制,包括其工作原理、常见问题及其解决方案。通过对Android内存模型的深入分析,本文将帮助开发者更好地理解内存分配、回收以及优化策略,从而提高应用性能和用户体验。
|
Android开发 开发者
Android性能优化——内存管理的艺术
Android性能优化——内存管理的艺术
|
监控 算法 数据可视化
深入解析Android应用开发中的高效内存管理策略在移动应用开发领域,Android平台因其开放性和灵活性备受开发者青睐。然而,随之而来的是内存管理的复杂性,这对开发者提出了更高的要求。高效的内存管理不仅能够提升应用的性能,还能有效避免因内存泄漏导致的应用崩溃。本文将探讨Android应用开发中的内存管理问题,并提供一系列实用的优化策略,帮助开发者打造更稳定、更高效的应用。
在Android开发中,内存管理是一个绕不开的话题。良好的内存管理机制不仅可以提高应用的运行效率,还能有效预防内存泄漏和过度消耗,从而延长电池寿命并提升用户体验。本文从Android内存管理的基本原理出发,详细讨论了几种常见的内存管理技巧,包括内存泄漏的检测与修复、内存分配与回收的优化方法,以及如何通过合理的编程习惯减少内存开销。通过对这些内容的阐述,旨在为Android开发者提供一套系统化的内存优化指南,助力开发出更加流畅稳定的应用。
442 31
|
Java 测试技术 Android开发
Android性能测试——发现和定位内存泄露和卡顿
本文详细介绍了Android应用性能测试中的内存泄漏与卡顿问题及其解决方案。首先,文章描述了使用MAT工具定位内存泄漏的具体步骤,并通过实例展示了如何分析Histogram图表和Dominator Tree。接着,针对卡顿问题,文章探讨了其产生原因,并提供了多种测试方法,包括GPU呈现模式分析、FPS Meter软件测试、绘制圆点计数法及Android Studio自带的GPU监控功能。最后,文章给出了排查卡顿问题的四个方向,帮助开发者优化应用性能。
1187 4
Android性能测试——发现和定位内存泄露和卡顿
|
编解码 Android开发 UED
构建高效Android应用:从内存优化到用户体验
【10月更文挑战第11天】本文探讨了如何通过内存优化和用户体验改进来构建高效的Android应用。介绍了使用弱引用来减少内存占用、懒加载资源以降低启动时内存消耗、利用Kotlin协程进行异步处理以保持UI流畅,以及采用响应式设计适配不同屏幕尺寸等具体技术手段。
213 2
|
监控 Java Android开发
探究Android应用开发中的内存泄漏检测与修复
在移动应用的开发过程中,优化用户体验和提升性能是至关重要的。对于Android平台而言,内存泄漏是一个常见且棘手的问题,它可能导致应用运行缓慢甚至崩溃。本文将深入探讨如何有效识别和解决内存泄漏问题,通过具体案例分析,揭示内存泄漏的成因,并提出相应的检测工具和方法。我们还将讨论一些最佳实践,帮助开发者预防内存泄漏,确保应用稳定高效地运行。
265 24