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

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

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


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


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


写在后面


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

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

相关文章
|
10天前
|
存储 设计模式 监控
运用Unity Profiler定位内存泄漏并实施对象池管理优化内存使用
【7月更文第10天】在Unity游戏开发中,内存管理是至关重要的一个环节。内存泄漏不仅会导致游戏运行缓慢、卡顿,严重时甚至会引发崩溃。Unity Profiler作为一个强大的性能分析工具,能够帮助开发者深入理解应用程序的内存使用情况,从而定位并解决内存泄漏问题。同时,通过实施对象池管理策略,可以显著优化内存使用,提高游戏性能。本文将结合代码示例,详细介绍如何利用Unity Profiler定位内存泄漏,并实施对象池来优化内存使用。
24 0
|
13天前
|
Prometheus 监控 Cloud Native
如何优化Java应用的内存使用
如何优化Java应用的内存使用
|
10天前
|
缓存 监控 算法
Java内存怎么优化
【7月更文挑战第11天】Java内存怎么优化
17 3
|
10天前
|
缓存 Prometheus 监控
Java面试题:如何监控和优化JVM的内存使用?详细讲解内存调优的几种方法
Java面试题:如何监控和优化JVM的内存使用?详细讲解内存调优的几种方法
30 3
|
10天前
|
设计模式 存储 安全
Java面试题:设计一个线程安全的单例类并解释其内存占用情况?使用Java多线程工具类实现一个高效的线程池,并解释其背后的原理。结合观察者模式与Java并发框架,设计一个可扩展的事件处理系统
Java面试题:设计一个线程安全的单例类并解释其内存占用情况?使用Java多线程工具类实现一个高效的线程池,并解释其背后的原理。结合观察者模式与Java并发框架,设计一个可扩展的事件处理系统
22 1
|
1天前
|
存储 缓存 算法
操作系统中的内存管理优化策略
随着计算机技术的飞速发展,操作系统作为连接硬件与软件的桥梁,其性能的优劣直接影响着整个计算机系统的运行效率。在众多影响系统性能的因素中,内存管理无疑是至关重要的一环。本文将深入探讨现代操作系统中内存管理的优化策略,包括分页机制、虚拟内存技术、缓存策略等,旨在揭示这些技术如何提升系统性能并减少资源浪费。通过分析不同内存管理技术的优势与局限,本文为读者提供了对操作系统内存管理深度理解的同时,也指出了未来可能的发展方向。
7 0
|
5天前
|
SQL 资源调度 关系型数据库
实时计算 Flink版产品使用问题之在使用Flink on yarn模式进行内存资源调优时,如何进行优化
实时计算Flink版作为一种强大的流处理和批处理统一的计算框架,广泛应用于各种需要实时数据处理和分析的场景。实时计算Flink版通常结合SQL接口、DataStream API、以及与上下游数据源和存储系统的丰富连接器,提供了一套全面的解决方案,以应对各种实时计算需求。其低延迟、高吞吐、容错性强的特点,使其成为众多企业和组织实时数据处理首选的技术平台。以下是实时计算Flink版的一些典型使用合集。
|
10天前
|
设计模式 存储 缓存
Java面试题:结合设计模式与并发工具包实现高效缓存;多线程与内存管理优化实践;并发框架与设计模式在复杂系统中的应用
Java面试题:结合设计模式与并发工具包实现高效缓存;多线程与内存管理优化实践;并发框架与设计模式在复杂系统中的应用
15 0
|
10天前
|
设计模式 存储 缓存
Java面试题:结合建造者模式与内存优化,设计一个可扩展的高性能对象创建框架?利用多线程工具类与并发框架,实现一个高并发的分布式任务调度系统?设计一个高性能的实时事件通知系统
Java面试题:结合建造者模式与内存优化,设计一个可扩展的高性能对象创建框架?利用多线程工具类与并发框架,实现一个高并发的分布式任务调度系统?设计一个高性能的实时事件通知系统
16 0
|
10天前
|
设计模式 并行计算 安全
Java面试题:如何使用设计模式优化多线程环境下的资源管理?Java内存模型与并发工具类的协同工作,描述ForkJoinPool的工作机制,并解释其在并行计算中的优势。如何根据任务特性调整线程池参数
Java面试题:如何使用设计模式优化多线程环境下的资源管理?Java内存模型与并发工具类的协同工作,描述ForkJoinPool的工作机制,并解释其在并行计算中的优势。如何根据任务特性调整线程池参数
13 0