| 关键词:应用程序 内存 选择 图像 Android 本机 视图 对象 组件 |
应用程序性能的一个关键方面是内存消耗。 测试内存泄漏并防止它们是每个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释放内存? 让我们逐步解释一下:
那么我们如何解决这个问题呢? 也许你刚刚猜到 - 用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()方法,它破坏了这个容器中的所有视图。 在与开发人员进行讨论和调试会话之后,引入了修复程序并删除了模板中的泄漏! 结论应用程序工作流程的性能分析是测试过程的关键部分。 确保应用程序运行良好应该是每个应用程序开发团队的目标。 内存使用是应用程序生命周期的关键部分,使用过多的内存可能会导致崩溃,数据丢失和客户不满意(这不是一个理想的场景!)。 执行内存分析既简单,快速,愉快,其结果可能并将导致更好的应用程序和更愉快的客户。 |
| 本文出处: https://www.toutiao.com/a6654197109350203908/ |
|
声明:文章版权归原作者所有 部分文章转自互联网 如有侵权请联系
[邮箱地址] 删除
|