热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

Android应用中出现内存泄漏的原因有哪些

这期内容当中小编将会给大家带来有关Android应用中出现内存泄漏的原因有哪些,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望

这期内容当中小编将会给大家带来有关Android应用中出现内存泄漏的原因有哪些,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。

正确的生命周期管理如何防止Android内存泄漏

OutOfMemoryException是一个常见的令人沮丧的错误,也是导致应用程序意外关闭的主要原因之一。

“如果应用程序昨天运行良好,为什么现在会发生这种情况?这个问题让Android的开发者和新手都感到困惑。

导致OutOfMemory异常的潜在原因有很多种,但其中最常见的是内存泄漏—应用程序中的内存分配从未释放。本文将解释如何通过有效的生命周期管理(开发过程中一个重要但经常被忽视的部分)来最小化这种风险。

为什么安卓系统会发生内存泄漏?

问题很简单。某些对象应该只有一个固定的寿命,当它们的使用寿命结束时,它们需要被删除。

Android应用中出现内存泄漏的原因有哪些

理论上,当进程使用onStop或onDestroy终止时,应该处理该内存。但是,滥用对象引用可能会阻止垃圾收集器释放未使用的对象。例如:如果未使用的对象A引用了未使用的对象B,那么您将得到两个不必要的对象,垃圾回收器将永远不会释放它们,因为它们正在相互引用。

阻止内存泄漏这种情况发生的常见技巧

开发人员可以采取许多步骤来阻止死的活动被困在内存中。

  1. 在onResume()/onPause()或onStart()/onStop()中注册/注销广播接收器

  2. 不要对视图/活动/上下文使用静态变量

  3. 需要保存对上下文的引用的singleton应该使用applicationContext()或将其包装到WeakReference中

  4. 注意匿名和非静态内部类,因为它们包含对其封闭类的隐式引用。

  5. 如果要比父类(如处理程序)更长寿,请使用静态内部类而不是匿名类。

  6. 如果内部或匿名类是可取消的(如AsyncTask、Thread、RxSubscriptions),则在销毁活动时取消它。

Android生命周期感知组件

一旦你完成了上面的基本步骤,现在是时候做一些更重要的事情了:应用程序活动的生命周期。如果我们不能正确地管理生命周期,我们最终会在不再需要内存的时候挂掉它。

这涉及到许多不同的任务。对于每个活动,我们需要中断线程,去掉RxJava中的订阅,取消AsyncTask引用,并确保正确删除该活动的引用(以及与之相关的任何其他活动)。所有这些任务都会消耗开发人员的大量时间。

模型视图呈现器(MVP)使事情变得更加复杂,MVP是Android中构建用户界面的常用架构模式。然而,MVP对于从视图中分离业务逻辑非常有用。

在MVP模式中,View和Presenter都是它们之间行为契约的抽象实现。实现MVP最常见的方法是使用活动/片段作为视图的实现,并为习惯于引用视图的演示者使用简单的实现。

所以我们最终得到了一个带有Presenter引用的视图和一个带有视图引用的Presenter(提示:这里有一个潜在的漏洞)。

考虑到这些潜在的困难,我们有必要建立一个适当的管理结构来移除在生命周期中创建的多余内存。有几种行之有效的方法可以做到这一点:

1. 在Android Studio上使用Android Arch Lifecycle创建支持生命周期的组件

生命周期感知组件是智能的。例如,它们可以通过除去内存来对另一个组件(如活动或片段)的生命周期状态的更改作出反应。这意味着代码更轻,内存效率更高。

archlifecycle是Android的一个新库,它提供了一组工具来构建支持生命周期的组件。库以抽象的方式工作,这意味着生命周期所有者不再需要担心管理特定任务和活动的生命周期。

Arch生命周期的关键工具和定义如下:

  • 生命周期:一个排序系统,它定义了哪些对象具有Android生命周期,并允许对它们进行监视。

  • LifecycleObserver:一个常规接口,它监视每个被标识为具有Android生命周期的对象,使用一个简单的公式来处理每个密钥生命周期事件。

  • @OnLifecycleEvent:可以在实现LifecycleObserver接口的类中使用的注释。它允许我们设置关键生命周期事件,这些事件将在每次启动时触发带注释的方法。以下是可设置的所有事件的列表:ON_ANY、ON_CREATE、ON_DESTROY、ON_PAUSE、ON_RESUME、ON_START、ON_STOP

  • LifecycleOwner默认为每个可以管理其生命周期的Android组件实现,并让开发人员控制每个事件。

使用这些工具,我们可以将所有干净的任务发送给它们的所有者(在我们的例子中是演示者),这样我们就有了一个干净的、无泄漏的解耦代码(至少在演示者层是这样)。

下面是一个超级基本的实现,向您展示我们所说的:

interface View: MVPView, LifecycleOwner

class RandomPresenter : Presenter, LifecycleObserver {
 private lateinit var view: View
 override fun attachView(view: View) {
  this.view = view
  view.lifecycle.addObserver(this)
 }

 @OnLifecycleEvent(Lifecycle.Event.On_DESTROY)
 fun onClear() {
	//TODO: clean 
}

2. 使用Android架构视图模型作为演示者和LiveData

另一种方法是通过使用新的生命周期组件来避免视图模型的内存泄漏。

ViewModel是一个抽象类,它实现一个称为onClear的函数,当必须删除某个特定对象时,该函数会自动调用。ViewModel是由框架生成的,它附加到创建者的生命周期中(作为一个额外的好处,使用Dagger注入非常容易)

除了使用ViewModel,LiveData还提供了一个重要的通信渠道。这意味着创造了一个容易观察到的反应性产物。

这里最重要的一点是,生命周期所有者可以观察到LiveData,因此数据传输总是由生命周期管理的,而且我们可以确保在使用它们时保留任何引用。

3. 使用LeakCanary和Bugfender

Android应用中出现内存泄漏的原因有哪些

除了上述步骤之外,我们还想推荐两个重要的工具包:LeakCanary,一个用于监视泄漏的流行工具,以及我们自己的Bugfender。

LeakCanary是一个用于Android和Java的内存检测库。它是开源的,所以有一个庞大的社区支持它,它不仅仅告诉你一个漏洞,它还告诉你可能的原因。

我们的远程日志工具Bugfender允许您调试单个泄漏跟踪,并扩展一个名为DisplayLeakService的类,它让我们知道何时发生泄漏。然后我们就可以用Bugfender轻松登录了。

public class LeakUploadService extends DisplayLeakService {
 override fun afterDefaultHandling(heapDump: HeapDump, result: AnalysisResult, leakInfo: String) {
  if (result.leakFound) {
   Bugfender.d(“LeakCanary”, result.toString())
  }
 }
}

此外,用户还可以获得Bugfender的所有其他好处,包括全天候记录日志(即使设备离线)、内置故障报告和易于使用的web控制台。

上述就是小编为大家分享的Android应用中出现内存泄漏的原因有哪些了,如果刚好有类似的疑惑,不妨参照上述分析进行理解。如果想知道更多相关知识,欢迎关注编程笔记行业资讯频道。


推荐阅读
  • 拥抱Android Design Support Library新变化(导航视图、悬浮ActionBar)
    转载请注明明桑AndroidAndroid5.0Loollipop作为Android最重要的版本之一,为我们带来了全新的界面风格和设计语言。看起来很受欢迎࿰ ... [详细]
  • 在Android开发中,使用Picasso库可以实现对网络图片的等比例缩放。本文介绍了使用Picasso库进行图片缩放的方法,并提供了具体的代码实现。通过获取图片的宽高,计算目标宽度和高度,并创建新图实现等比例缩放。 ... [详细]
  • 本文介绍了在开发Android新闻App时,搭建本地服务器的步骤。通过使用XAMPP软件,可以一键式搭建起开发环境,包括Apache、MySQL、PHP、PERL。在本地服务器上新建数据库和表,并设置相应的属性。最后,给出了创建new表的SQL语句。这个教程适合初学者参考。 ... [详细]
  • android listview OnItemClickListener失效原因
    最近在做listview时发现OnItemClickListener失效的问题,经过查找发现是因为button的原因。不仅listitem中存在button会影响OnItemClickListener事件的失效,还会导致单击后listview每个item的背景改变,使得item中的所有有关焦点的事件都失效。本文给出了一个范例来说明这种情况,并提供了解决方法。 ... [详细]
  • Android Studio Bumblebee | 2021.1.1(大黄蜂版本使用介绍)
    本文介绍了Android Studio Bumblebee | 2021.1.1(大黄蜂版本)的使用方法和相关知识,包括Gradle的介绍、设备管理器的配置、无线调试、新版本问题等内容。同时还提供了更新版本的下载地址和启动页面截图。 ... [详细]
  • 本文介绍了RPC框架Thrift的安装环境变量配置与第一个实例,讲解了RPC的概念以及如何解决跨语言、c++客户端、web服务端、远程调用等需求。Thrift开发方便上手快,性能和稳定性也不错,适合初学者学习和使用。 ... [详细]
  • 本文介绍了RxJava在Android开发中的广泛应用以及其在事件总线(Event Bus)实现中的使用方法。RxJava是一种基于观察者模式的异步java库,可以提高开发效率、降低维护成本。通过RxJava,开发者可以实现事件的异步处理和链式操作。对于已经具备RxJava基础的开发者来说,本文将详细介绍如何利用RxJava实现事件总线,并提供了使用建议。 ... [详细]
  • UEditor可以如何直接复制word的图文内容到编辑器中
    这种方法是servlet,编写好在web.xml里配置servlet-class和servlet-mapping即可使用后台(服务端)j ... [详细]
  • 推荐:看到如此多的MVP+Dagger2+Retrofit+Rxjava项目,轻松拿star,心动了吗?看到身边的朋友都已早早在项目中使用这些技术,而你还不会,失落吗?MVPArm ... [详细]
  • 本文由编程笔记#小编为大家整理,主要介绍了logistic回归(线性和非线性)相关的知识,包括线性logistic回归的代码和数据集的分布情况。希望对你有一定的参考价值。 ... [详细]
  • 本文分享了一个关于在C#中使用异步代码的问题,作者在控制台中运行时代码正常工作,但在Windows窗体中却无法正常工作。作者尝试搜索局域网上的主机,但在窗体中计数器没有减少。文章提供了相关的代码和解决思路。 ... [详细]
  • Linux重启网络命令实例及关机和重启示例教程
    本文介绍了Linux系统中重启网络命令的实例,以及使用不同方式关机和重启系统的示例教程。包括使用图形界面和控制台访问系统的方法,以及使用shutdown命令进行系统关机和重启的句法和用法。 ... [详细]
  • 本文介绍了C#中生成随机数的三种方法,并分析了其中存在的问题。首先介绍了使用Random类生成随机数的默认方法,但在高并发情况下可能会出现重复的情况。接着通过循环生成了一系列随机数,进一步突显了这个问题。文章指出,随机数生成在任何编程语言中都是必备的功能,但Random类生成的随机数并不可靠。最后,提出了需要寻找其他可靠的随机数生成方法的建议。 ... [详细]
  • 《数据结构》学习笔记3——串匹配算法性能评估
    本文主要讨论串匹配算法的性能评估,包括模式匹配、字符种类数量、算法复杂度等内容。通过借助C++中的头文件和库,可以实现对串的匹配操作。其中蛮力算法的复杂度为O(m*n),通过随机取出长度为m的子串作为模式P,在文本T中进行匹配,统计平均复杂度。对于成功和失败的匹配分别进行测试,分析其平均复杂度。详情请参考相关学习资源。 ... [详细]
  • 利用Visual Basic开发SAP接口程序初探的方法与原理
    本文介绍了利用Visual Basic开发SAP接口程序的方法与原理,以及SAP R/3系统的特点和二次开发平台ABAP的使用。通过程序接口自动读取SAP R/3的数据表或视图,在外部进行处理和利用水晶报表等工具生成符合中国人习惯的报表样式。具体介绍了RFC调用的原理和模型,并强调本文主要不讨论SAP R/3函数的开发,而是针对使用SAP的公司的非ABAP开发人员提供了初步的接口程序开发指导。 ... [详细]
author-avatar
mobiledu2502853473
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有