基于跨端框架项目的内存问题优化

简介: 基于跨端框架项目的内存问题优化

640.jpg写在前面


目前,业内的跨端框架不少:react-native,weex,hippy,taro等等。采用跨端框架的项目一般都依附于客户端而存在,由前端同学开发。为了避免客户端发生crash,相对于传统浏览器上的前端页面开发,跨端项目对于内存管理、CPU利用率的要求更高。

本文将以某App上的小说阅读器为例,讲解在对项目代码完全不了解的情况下,如何进行内存问题的优化。


小说的用户场景比较简单:打开一部小说,一直滑动阅读即可。


前期工作


第一步,我们需要工具,来量化项目的内存表现。perfdog 是常用的工具之一。使用很简单,手机连上电脑,打开perdog,打开想要测试的应用,进行操作,就可以看到实时的内存和CPU表现了。


640.png


由于虚拟内存达到某一个临界值后,会导致APP直接crash;所以需要明确最重要的衡量指标:1、一顿操作后的虚拟内存增量。2、峰值虚拟内存


开始优化


优化方向


前文已经讲到,我们优化的衡量指标是:虚拟内存峰值、增量

造成内存增加的原因主要是:

1、业务需要,在内存里面储存了业务数据

2、内存泄露导致无法按预期进行GC

对于第一点,并不具有普适性,需要具体情况具体分析。第二点是我们优化的着重发力点。


优化步骤


以react为例,说起内存问题优化(避免内存泄露),方法都耳熟能详:

1、定时器需要清除 ; 2、注意闭包的使用;3、组件销毁时需要清除对其的引用;4、使用发布订阅模式时,组件销毁时,需要移除事件监听;5、注意全局变量的使用。。。。。

但是在对业务代码完全不熟悉,并且业务代码量巨大时,直接从几万行代码入手或许不是最好的选择。


1、采集内存增量


怎么找到可优化或者说内存泄露的地方呢?perfdog可以帮助我们查看实时内存,但是没有办法细化到具体的内存。作为前端开发,我们可以利用常用的chrome inspector的内存快照工具帮助我们进行分析。


640.png

640.png



我们想要测试的是内存增量。在开始操作前,先记录一次内存快照。接着模拟用户,进行一系列操作。操作完成后,手动触发一次gc,再记录一次内存快照。查看这两次快照之间的差异,来判断内存增量的由来。


640.png


至此,我们就可以看到我们的操作所带来的内存增量了。接下来开始进行分析。


2、分析内存增量

以本文提及的小说场景为例,在滑动了小说几个章节后,发现某组件对象数量增加了很多,但是一个也没有被删除。点开其中一个对象实例,查看其引用链,发现被其外层组件所引用了。

640.png



通过关键变量名,可以迅速定位到问题代码,进行修复。最终发现父组件中,有一个变量持有了所有的子组件,导致被销毁的子组件无法被GC,造成泄漏。


再举一个例子:


640.png


从上面的图中我们可以发现,Promise实例数也是只增加,不减少。点开其中一个Promise进行排查,发现大量Promise一直处于pending状态。这里肯定是有问题的。


其余不少组件也存在实例数只增加不减少的情况,点开其中一个组件发现:


640.png


组件内部引用的Promise一直pending,导致该组件也被系统一直持有了,无法释放,一切都是卡住的Promise的锅。

通过查看Promise的持有链,最终发现是由于一个Bug,导致了部分Promise一直无法resolve或reject,导致了内存泄露。修复Bug后,问题解决。


这里举了两个例子,说明了如何利用内存快照进行问题分析,总结一下:


拿到内存增量后,我们需要重点关注那些新增数量特别多,但是删除数量特别少的对象,很可能其中就有内存泄露,或者有明显的优化空间


3、采集数据、分析优化效果


优化完成后,如何衡量优化效果呢?用数据说话。chrome inspector一般是用来调试的,严谨的采集数据需要借助其他工具。文章开头我们介绍了perfdog的使用方法,但是这里用人工来测试是不太现实的,我们可以使用简单的工具来辅助我们进行测试。

以Android为例,


1、首先安装adb工具,安装教程:https://www.jianshu.com/p/1b3fb1f27b67

2、接着连接手机,切换到想要测试的场景,使用 adb shell 来辅助测试。

以小说阅读场景为例,使用下面的命令可以控制测试手机自动翻页:


adb shell "input swipe 1000 1300 50 1300 1000"

3、然后我们可以使用Node.js写一个简单的脚本,就可以开启简陋的“自动化”测试了。下面就是一个自动左右滑动小说1000页的简易脚本


640.png

4、再结合perfdog,我们就可以得到内存和CPU的表现数据了。perfdog可以将数据导出成excel文件,开始采集数据时,点击perfdog右上角的开始按钮,结束时点击暂停按钮,即可导出数据。数据里面包括了每一秒钟的CPU、内存表现。


640.png


最后,通过人工或脚本的方法,便可以很方便的统计出虚拟内存增量,峰值虚拟内存,最终产出优化效果报告。


注意,采集数据的时候,需要等待客户端内存稳定后再开始,否则对最后的结果会产生较大影响。并且,每一次测试,需要固定测试路径,排除其他变量带来的干扰。


写在后面


本文主要是从一个前端工程师的角度,以基于跨端框架的项目为例,说明了如何实施一次内存问题优化。更进一步,可以和客户端同学配合,达到更加深度的优化效果。

在对项目代码完全不了解的情况下,我们可能无法直接从代码入手,一行一行死磕。可以借助工具,按照本文的思路进行分析,然后再对症下药。这是一项有迹可循的系统性工程。至于网络上的大部分优化宝典,更多的是作用于开发阶段。在开发时就应该养成良好的编码习惯和意识,最大限度的避免问题的发生。

相关文章
|
1月前
|
存储 缓存 监控
|
1月前
|
缓存 算法 Java
Java中的内存管理:理解与优化
【10月更文挑战第6天】 在Java编程中,内存管理是一个至关重要的主题。本文将深入探讨Java内存模型及其垃圾回收机制,并分享一些优化内存使用的策略和最佳实践。通过掌握这些知识,您可以提高Java应用的性能和稳定性。
46 4
|
9天前
|
缓存 算法 Java
本文聚焦于Java内存管理与调优,介绍Java内存模型、内存泄漏检测与预防、高效字符串拼接、数据结构优化及垃圾回收机制
在现代软件开发中,性能优化至关重要。本文聚焦于Java内存管理与调优,介绍Java内存模型、内存泄漏检测与预防、高效字符串拼接、数据结构优化及垃圾回收机制。通过调整垃圾回收器参数、优化堆大小与布局、使用对象池和缓存技术,开发者可显著提升应用性能和稳定性。
30 6
|
9天前
|
监控 安全 程序员
如何使用内存池池来优化应用程序性能
如何使用内存池池来优化应用程序性能
|
9天前
|
存储 监控 Java
深入理解计算机内存管理:优化策略与实践
深入理解计算机内存管理:优化策略与实践
|
21天前
|
存储 JavaScript 前端开发
如何优化代码以避免闭包引起的内存泄露
本文介绍了闭包引起内存泄露的原因,并提供了几种优化代码的策略,帮助开发者有效避免内存泄露问题,提升应用性能。
|
22天前
|
并行计算 算法 IDE
【灵码助力Cuda算法分析】分析共享内存的矩阵乘法优化
本文介绍了如何利用通义灵码在Visual Studio 2022中对基于CUDA的共享内存矩阵乘法优化代码进行深入分析。文章从整体程序结构入手,逐步深入到线程调度、矩阵分块、循环展开等关键细节,最后通过带入具体值的方式进一步解析复杂循环逻辑,展示了通义灵码在辅助理解和优化CUDA编程中的强大功能。
|
1月前
|
存储 弹性计算 算法
前端大模型应用笔记(四):如何在资源受限例如1核和1G内存的端侧或ECS上运行一个合适的向量存储库及如何优化
本文探讨了在资源受限的嵌入式设备(如1核处理器和1GB内存)上实现高效向量存储和检索的方法,旨在支持端侧大模型应用。文章分析了Annoy、HNSWLib、NMSLib、FLANN、VP-Trees和Lshbox等向量存储库的特点与适用场景,推荐Annoy作为多数情况下的首选方案,并提出了数据预处理、索引优化、查询优化等策略以提升性能。通过这些方法,即使在资源受限的环境中也能实现高效的向量检索。
|
1月前
|
数据处理 Python
如何优化Python读取大文件的内存占用与性能
如何优化Python读取大文件的内存占用与性能
115 0
|
2月前
|
Java Android开发 UED
安卓应用开发中的内存管理优化技巧
在安卓开发的广阔天地里,内存管理是一块让开发者既爱又恨的领域。它如同一位严苛的考官,时刻考验着开发者的智慧与耐心。然而,只要我们掌握了正确的优化技巧,就能够驯服这位考官,让我们的应用在性能和用户体验上更上一层楼。本文将带你走进内存管理的迷宫,用通俗易懂的语言解读那些看似复杂的优化策略,让你的开发之路更加顺畅。
60 2