安基网 首页 编程 软件学院 查看内容

使用Android Studio和Xcode找出应用内存泄漏点

2019-2-6 00:57| 投稿: xiaotiger |来自: 互联网


免责声明:本站系公益性非盈利IT技术普及网,本文由投稿者转载自互联网的公开文章,文末均已注明出处,其内容和图片版权归原网站或作者所有,文中所述不代表本站观点,若有无意侵权或转载不当之处请从网站右下角联系我们处理,谢谢合作!

摘要: 应用程序性能的一个关键方面是内存消耗。 测试内存泄漏并防止它们是每个QA和应用程序开发人员应执行的主要任务之一。 内存泄漏可能导致应用程序性能不佳甚至应用程序崩溃,这会降低应用程序用户的满意度,甚至可能导 ...

应用程序性能的一个关键方面是内存消耗。 测试内存泄漏并防止它们是每个QA和应用程序开发人员应执行的主要任务之一。 内存泄漏可能导致应用程序性能不佳甚至应用程序崩溃,这会降低应用程序用户的满意度,甚至可能导致您丢失它们。 在这篇文章中,我将向您展示如何追逐它们,找到大多数内存泄漏的位置,以及如何解决它们。

先决条件

此任务的先决条件是几个工具,可帮助我们在运行时深入挖掘应用程序并分析其行为。 我将向您展示如何使用Xcode instruments和Android Studio Profiler配置原生iOS和原生Android应用程序。 您可以分别直接从macOS App Store和developer.android.com下载它们。 这些工具用于查看内存,线程和进程,方法计时和网络使用等资源。

Android

构建NativeScript应用程序后,application/platforms文件夹中有两个本机应用程序。 从android开始我们需要打开Android Studio并选择“Profile or debug APK”选项并打开我们应用的.apk文件:

当Android Studio准备就绪时,我们必须手动设置一个配置。 应配置项目的Android SDK - 打开文件菜单并选择Project Structure。 在打开的窗口中,在Project SDK下拉列表中选择Android SDK,然后转到Modules并再次在Module SDK下拉列表中选择Android SDK。 将更改应用于项目并准备启动。

在Android Studio的功能区中有一个图标“配置文件”,单击图标将打开一个包含当前可用设备的窗口,选择一个,单击确定按钮并开始搜索。 请记住,应用标识符应该是唯一的。 如果应用程序已安装在设备上,则应使用adb install -r命令。

在窗口中,您可以看到CPU,内存和网络的指标,单击内存指标将展开内容并显示更详细的图表,我们可以在其中监控正在运行的应用程序的内存使用情况。

主要的内存消耗组件是那些使用数据的组件 - 列表,画廊,网格,图表等。狩猎内存泄漏应该指向这些组件。 在我们的示例中,我们有一个Image区域组件,它显示了gallery中的图像。 每次选择图像时,预计使用的内存大小会增加。 但是,选择另一个图像或再次显示相同的图像不应该增加使用的内存。 开发人员应该正确地选择一种技术,并且应该释放未使用的内存和对象。

在我们的示例中,我们看到没有泄漏,在一个接一个地选择图像后,释放第一个图像的内存。 我们看到该系列的内存使用量的上升和下降。

iOS版

让我们尝试iOS的相同示例,看看会发生什么。

此处的过程与Android中的过程相同,其中一些细节与iOS应用程序开发和调试过程相关。

同样,我们首先在XCode(位于platforms/ios文件夹中)打开本机应用程序的项目或工作区。 然后,转到产品 - >配置文件菜单,然后选择配置文件选项。 构建应用程序并将其部署到设备后,将显示带有选项的窗口。 对于此测试,我们将选择Allocations选项。 当显示配置文件时,我们只需按下窗口左上角的红色“录制”按钮,即可开始观看图表。 最初,该应用程序使用16-17 MB内存。 当我们开始在应用程序中选择图像时,我们看到图表上升了一点,但是一旦我们开始选择第二个,第三个等图像,内存消耗就会线性增长,这是我们不希望发生的事情。

这看起来像我们的应用程序中的内存泄漏:

然而,经过一些进一步的调查后,事实证明,在某些时刻,虽然很少,整体内存使用量下降,然后在图像选择后再次开始上升。 因此,这并不是一个泄漏,因为最终,似乎ARC(自动引用计数,iOS中垃圾收集的替代)机制通过释放不需要的对象来设法释放内存。 问题只是内存的高使用率,在ARC不释放这些大对象的情况下,这可能对应用程序执行造成致命的影响。

但为什么会这样呢? 什么阻止ARC释放内存? 让我们逐步解释一下:

  • 在选择图像时,nativescript-imagepicker插件API将图像的JS对象表示返回给应用程序。
  • 在我们的例子中,每个JS对象都有它们的原生对应物 - 使用大量内存的图像(大对象)。
  • JS对象本身很小,以至于JavaScript VM中的内存使用量从未达到触发垃圾回收的程度。
  • 因此,许多小JS对象导致JS世界中本机端的高内存使用。 只有当JS中的内存压力升高时,才会触发JS中的GC并释放所有本机对应物。

那么我们如何解决这个问题呢? 也许你刚刚猜到 - 用JavaScript触发垃圾收集! 虽然它听起来不是最好的解决方案,但它似乎是目前唯一的解决方案。 让我们看看我们的图形是什么样的:

确实工作 - 一旦垃圾收集JS对象释放了它们的引用,就释放本机对象。

虚拟内存泄漏

虚拟内存泄漏是发生在应用程序的UI部分中的那些。 在浏览页面时将UI组件(如标签,按钮等)相乘。 视图不会从列表中删除,在刷新后将它们在网格中相乘,还有更多是内存方面泄漏的示例。 让我们看一个使用带有“pull to refresh”功能的ListView的示例。

NativeScript CLI具有调试iOS和Android应用程序的内置功能,并检查Google Chrome开发人员工具窗口中的UI元素。

今天我们将在master-detail应用程序模板中使用ListView组件:

从模板创建应用程序:

tns create masterDetailApp --tns-template-master-detail

...然后运行tns debug android命令并等待应用程序构建。 然后打开Chrome浏览器并访问控制台中CLI打印的链接。

在浏览器开发工具的Memory选项卡中,我们看到一个用于创建JavaScript堆快照的按钮。 获取应用程序的初始快照以供参考,并查看列出的元素。 键入“image”过滤搜索栏中的元素。 我们看到模板有四个从ListView加载的图像:

我们还可以看到他们的ID。 通过触发“拉动刷新”,我们期望刷新ListView的源并且项目保持相同的计数,但如果我们在拍摄新快照后再次过滤图像,我们会看到他们的计数加倍,并且它们是 现在八点!

显然,ListView组件存在一个错误 - 一旦它们不再被使用(即对用户可见),它的项目/视图应该被垃圾收集器删除。

让我们来看看我们是如何发现泄漏的。 第一个快照中的四个元素不应出现在第二个快照中,但如果我们看到它们仍然在那里。 当我们检查它们时,我们看到renderElement保留器中第一次出现的RadListView位于由ViewContainerRef创建的_itemTemplate中。

在Angular中创建视图时的常见情况是使用ViewContainerRef来完成。 它最常被开发人员使用,是在Pages中创建嵌入视图的常用方法之一。 它隐藏了漏洞,因为容器应该在使用结束时清除。 如果未调用clear方法,即使触发了垃圾收集器,所有视图仍将保持未清除状态。 原因是因为ViewContainerRef本身持有对创建的嵌入视图的引用,因此无法将它们标记为垃圾回收。

现在,当我们知道是什么创建了视图时,我们应该找到一种方法来清理它们。 在Angular文档中搜索,我们发现ViewContainerRef有一个clear()方法,它破坏了这个容器中的所有视图。 在与开发人员进行讨论和调试会话之后,引入了修复程序并删除了模板中的泄漏!

结论

应用程序工作流程的性能分析是测试过程的关键部分。 确保应用程序运行良好应该是每个应用程序开发团队的目标。 内存使用是应用程序生命周期的关键部分,使用过多的内存可能会导致崩溃,数据丢失和客户不满意(这不是一个理想的场景!)。 执行内存分析既简单,快速,愉快,其结果可能并将导致更好的应用程序和更愉快的客户。



小编推荐:欲学习电脑技术、系统维护、网络管理、编程开发和安全攻防等高端IT技术,请 点击这里 注册账号,公开课频道价值万元IT培训教程免费学,让您少走弯路、事半功倍,好工作升职加薪!

本文出自:https://www.toutiao.com/a6654197109350203908/

免责声明:本站系公益性非盈利IT技术普及网,本文由投稿者转载自互联网的公开文章,文末均已注明出处,其内容和图片版权归原网站或作者所有,文中所述不代表本站观点,若有无意侵权或转载不当之处请从网站右下角联系我们处理,谢谢合作!


鲜花

握手

雷人

路过

鸡蛋

相关阅读

最新评论

 最新
返回顶部