分析 ECharts 图表渲染导致的内存泄漏问题 - 附解决方案

news2024/9/23 17:19:26

一. 引言

在今年某个可视化大屏项目中,出现了一个问题。项目在运行一段时间后,页面出现了崩溃,而且是大概运行几天之后,因为大屏项目是部署到客户现场大屏,长时间运行不关闭。报错问题如下图所示:

image.png

由于这个大屏页面是使用 ECharts 图表渲染的,整个页面就一个渲染地图的功能,没有多少耗费内存的操作。而 ECharts 作为一款强大的数据可视化库,被广泛应用于各种项目中,因此 ECharts 的稳定性也是经过广大开发者验证的,不会出现明显的 bug 问题。

然而,我们也知道,如果页面随着图表数量的增加和动态更新的需求,我们必然会考虑 ECharts 图表渲染导致的内存泄漏问题。因此,上面的问题我们按照这个猜想来往下走,认为 ECharts 图表渲染导致了内存泄漏,那么 ECharts 的什么操作会导致内存泄漏、甚至到页面崩溃呢?

本文将深入分析这一问题,并提供解决方案。

二. 问题背景

猜测原因

当我们使用 ECharts 来渲染大量图表时,会发现页面的内存占用不断增加,最终导致页面卡顿甚至崩溃。这是由于 ECharts 在图表渲染过程中产生的内存泄漏导致的。

而奇怪的是,自己在本地中测试的时候,从未有过崩溃的现象?但是在客户现场就出现了这种问题。

Snipaste_2023-10-21_13-49-57.png

Snipaste_2023-10-21_13-49-57.png

内存占用检测

为了能够实时监测网站运行过程中,我们在 Chrome 浏览器打开了内存性能分析,便于实时查看内存占用情况,发现运行内存占用并不是太大,我们监测过一段时间后发现,确实内存有时在稳定的增加,但是这点内存占用还不至于导致系统崩溃。

image.png

内存泄漏原因分析

  • 嵌套事件绑定:在 ECharts 图表中,每个图表都会绑定各种交互事件。如果我们正确地解绑这些事件,则会导致事件监听器无法垃圾回收,从而造成内存泄漏。

  • 大量的图表实例:如果我们在动态更新图表的过程中,每次都创建新的图表实例而不销毁旧的实例,就会导致内存占用不断增加。

  • 定时器未清理:如果我们在更新图表的过程中使用了定时器来控制刷新频率,但未能正确清理这些定时器,就可能导致内存泄漏。

三. 第一轮解决方案

因为可视化大屏项目代码不是我直接写的,我当时只不过是被临时抽过去提过几个建议而已,所以并没有深入的研读项目代码,所以这一轮解决方案可以定义为是在浪费时间,不过也并不是一点经验没有,一起来看一下吧。

初步解决

为了解决 ECharts 图表渲染导致的内存泄漏问题,我们采取以下措施:

  • 在绑定事件监听器时,要确保正确解绑,可以使用 ECharts 提供的off方法来取消事件定。

  • 在图表组件销毁之前,务必使用 dispose 函数销毁图表实例,以确保释放内存。

  • 在动态更新图表时,尽量复用现有的图表实例,而不是每次都创建新的实例。可以使用 ECharts 提供的setOption方法来更新图表数据和配置。

  • 如果使用了定时器来控制图表的刷新频率,必须在组件销毁前清定时器,可以使用clearIntervalclearTimeout来停止定时器。

  • 正确管理图表组件的生命周期,尽量避免不必要的渲染和更新操作。

初步验证

按照以上的初步解决方案,我们对流程进行了初步优化,主要进行了事件监听器的绑定与解绑优化、销毁定时器、dispose 函数销毁图表实例等操作。

等这些优化操作完成后,我们又部署到自己的系统进行初步验证,发现内存占用确实变的小了,但是等到运行长时间来看,内存还是有上升的趋势。因此我断定,没有找到根本原因解决。

果然,运行了大概有五天的时间,浏览器还是顶不住了,系统再一次不工作了。

四. 第二轮解决方案

可能原因

由于这个大屏项目是其他同事开发的,具体的代码我并不太清楚。因此,先前只是提供了一些建设性的建议,没想到同事修改完成后还是没有解决了根本问题。所以可能必须要完全读懂项目的代码才能找到根本原因。

果然,看了几遍代码后发现了一些端倪,页面部署上之后是不会再进行操作了,数据会自动定时刷新,地图数据也会自动刷新,因此,问题就出现在这了。

猜想

多次调用 echarts.init,项目中这一段代码写的确实有问题,写了个定时器,每次刷新数据时,都需要调用 echarts init,并且销毁时 clear 和 dispose 方法使用不当造成,定时器循环重绘 ECharts 图表导致内存一直升高,最终导致了浏览器崩溃。

解决方案

通过 echarts init 方法创建 ECharts 实例,如果代码没有做优化,echarts 实例就会越来越多,占用大量内存,有以下两种方法可以避免这种情况:

第一种:使用 echarts init 之前先判断是否存在实例

const chart = echarts.getInstanceByDom(document.getElementById(dom));
if (chart === undefined) {
  chart = echarts.init(document.getElementById(dom));
}

第二种:如果 ECharts 存在,先 dispose 销毁后,再调用 init

const chart = echarts.getInstanceByDom(document.getElementById(dom));
if (chart) {
  echarts.dispose(chart);
}
chart = echarts.init(document.getElementById(dom));

验证

使用上述的代码进行优化,再结合第一轮的代码优化后。系统又重新部署了,监测系统内存状态,初始的内存占用大小和之前的相差不大。不过观察一段时间后,内存没有持续升高的趋势,还算比较稳定。又这样运行了大概有一周左右,发现内存占用仍然稳定,系统也没有出现过崩溃的问题。因此可以断定,应该是优化好了。

五. 总结

ECharts 图表渲染导致的内存泄漏问题是我们在使用 ECharts 时经常遇到的挑战之一。

在 ECharts 做图表开发时,避免内存泄漏的几点操作主要有以下几个方面:

  • 多次调用 echarts.init 会导致内存泄漏,应当在恰当时机销毁已经存在的 ECharts 实例,使用 clear() 和 dispose() 手动清理,区别在于:

    • clear()不会销毁实例,只是重新绘制图形,

    • dispose()会销毁实例,需要重新构建 ECharts 对象

  • 在动态更新图表时,尽量复用现有的图表实例,而不是每次都创建新的实例。可以使用 ECharts 提供的setOption方法来更新图表数据和配置。

  • 在绑定事件监听器时,要确保正确解绑,可以使用 ECharts 提供的off方法来取消事件。

通过深入分析内存泄漏的原因,并采取相应的解决方案,我们可以有效地解决这一问题,确保应用的稳定性和性能。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2126824.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

重磅发布!DeepSeek-V2.5:融合通用与代码能力的全新开源模型

前沿科技速递🚀 在人工智能飞速发展的今天,通用对话与代码生成的融合已经成为开发者高效工作的关键工具。近日,DeepSeek 团队正式发布了全新的 DeepSeek-V2.5 模型,一个强大的开源模型,它将通用语言处理与代码生成能力…

Python爱心射线

系列目录 序号直达链接表白系列1Python制作一个无法拒绝的表白界面2Python满屏飘字表白代码3Python无限弹窗满屏表白代码4Python李峋同款可写字版跳动的爱心5Python流星雨代码6Python漂浮爱心代码7Python爱心光波代码8Python普通的玫瑰花代码9Python炫酷的玫瑰花代码10Python多…

高效录屏攻略:电脑视频录制时声音同步捕获技巧,轻松搞定高清音质

在当今数字化时代,无论是在线教育、远程工作还是内容创作,录制视频已经成为我们生活中不可或缺的一部分。但是,很多人在录制视频时都会遇到一个问题:如何同时录制声音?如果你也在为此烦恼,那么这篇文章将为…

OpenCV通过鼠标提前ROI(C++实现)

文章目录 鼠标绘制矩形提取ROI任意形状绘制提前ROI 废话不多说&#xff0c;直接上代码 鼠标绘制矩形提取ROI #include <iostream> #include <opencv2\opencv.hpp> #include <opencv2/highgui/highgui.hpp> #include <opencv2/core/core.hpp>us…

算法_优先级队列---持续更新

文章目录 前言最后一块石头重量题目要求题目解析代码如下 数据流中的第K大元素题目要求题目解析代码如下 前K个高频单词题目要求题目解析代码如下 数据流的中位数题目要求题目解析代码如下 前言 本文将会向你分享优先级队列相关的题目&#xff1a;最后一块石头重量、数据流中的…

【运维自动化-作业平台】脚本版本管理如何使用

在蓝鲸作业平台中&#xff0c;执行脚本是最常见的功能之一&#xff0c;支持快速录入脚本执行和引用脚本执行&#xff0c;引用的脚步即单独写好的&#xff0c;并且由定期管理更新的脚本&#xff0c;主要有业务脚本和公共脚本两种。快速脚本 手动页面编写的脚本&#xff0c;没有…

将小写字母转换为大写字母(c 语言)

2.我们第一步输入字符串&#xff0c;第二步进行筛选将字符串中所以下标为奇数位置上的字母转换成大写&#xff0c;如果该位置不是字母&#xff0c;则不转换。 #include <stdio.h> #include <string.h> void fun( char *ss ) {int i 0;while (*ss ! \0){if (i % 2…

ACL 2024:交叉领域情感分析——论文阅读笔记

前言 阅读了一篇ABSA的论文&#xff0c;在这里写下自己的一些理解小笔记&#xff0c;可能有点小乱&#xff0c;原文在这下面&#xff1a; 论文链接&#xff1a;Refining and Synthesis: A Simple yet Effective Data Augmentation Framework for Cross-Domain Aspect-based Sen…

swoole协程 是单线程的,还是多线程的

Swoole 协程本质上是单线程的&#xff0c;但它可以在多个线程中运行。因此&#xff0c;Swoole 协程既可以看作是单线程的&#xff0c;也可以在多线程的环境下运行&#xff0c;这取决于你如何使用 Swoole。 理解 Swoole 协程的运行模式 1 单线程中的协程&#xff1a; 在一个单…

构建常态化安全防线:XDR的态势感知与自动化响应机制

当前&#xff0c;网络安全威胁日益复杂多变&#xff0c;企业正面临前所未有的严峻挑战。为有效应对这些挑战&#xff0c;态势感知与自动化响应机制在提升网络安全运营效率与防御效果中扮演着至关重要的角色。它们能够实时监测网络状态&#xff0c;智能分析潜在威胁&#xff0c;…

浏览器中的JavaScript核心BOM(浏览器对象模型)重点掌握对象之History对象的属性与方法

History对象是用来把网页浏览历史用类似栈的方式进行表示。 这定义听起来非常的抽象&#xff0c;其实History对象的作用就跟浏览器的前进和后退很像&#xff0c;我们来用几幅图来理解一下。首先我们先回顾一下浏览器的返回上一个页面 和 跳转到下一个页面 这两个功能。 就类似…

【计算机网络】网络通信中的端口号

文章目录 一、引入端口号二、端口号的作用三、端口号的确定 在TCP/IP协议中&#xff0c;传输层有两个重要的协议&#xff1a;TCP&#xff08;传输控制协议&#xff09;和UDP&#xff08;用户数据报协议&#xff09;。TCP用于提供可靠的数据传输&#xff0c;而UDP则适合用于广播…

labview对位项目

带角度对位 1、上下拍照对照 项目类型&#xff1a;模组、PACK入箱&#xff0c;以下以模组入箱为例 项目目标&#xff1a;机器人抓起模组&#xff0c;通过上相机定位箱体上的销钉&#xff0c;通过下相机定位模组上的端板孔&#xff0c;计算出旋转偏移量XYR&#xff0c;让模组上…

苹果能引领端侧AI大模型时代吗?

苹果能引领端侧AI时代吗&#xff1f; 这份完整版的大模型 AI 学习资料已经上传CSDN&#xff0c;朋友们如果需要可以微信扫描下方CSDN官方认证二维码免费领取【保证100%免费】 北京时间9月10日凌晨&#xff0c;苹果正式发布了iPhone 16&#xff0c;这是苹果第一款真正意义上的 …

精品PPT | 离散制造行业智能工厂总体解决方案

一、建设背景 离散制造业&#xff0c;包括机械制造业、汽车制造业和家电制造业等&#xff0c;其生产过程涉及多个不连续的工序&#xff0c;产品通常由多个零件装配而成。这类行业面临的挑战包括品种多、批量小、订单变化快、临时插单频繁以及外协件管理困难等问题&#xff0c;…

相机光学(三十七)——自动对焦原理

1.自动对焦的三种方式 目前在手机上采用的自动对焦系统包括反差对焦、相位对焦和激光对焦三种方案&#xff0c;下面我们来看一下它们的工作原理和相互之间的区别是什么。 1.1反差对焦【CDAF】- Contrast Detection Auto Focus 反差对焦是目前普及率最高、使用最广泛、成本相对…

Leetcode 701-二叉搜索树中的插入操作

给定二叉搜索树&#xff08;BST&#xff09;的根节点 root 和要插入树中的值 value &#xff0c;将值插入二叉搜索树。 返回插入后二叉搜索树的根节点。 输入数据 保证 &#xff0c;新值和原始二叉搜索树中的任意节点值都不同。 注意&#xff0c;可能存在多种有效的插入方式&a…

QT之QML学习五:添加自定义Qml组件

开发环境: 1、Qt 6.7.2 2、Pyside6 3、Python 3.11.4 4、Windows 10 重要的事情说三遍,使用自定义qml参考链接: Qt官网参考网址!!! 重要的事情说三遍,使用自定义qml参考链接: Qt官网参考网址!!! 重要的事情说三遍,使用自定义qml参考链接: Qt官网参考网址!!!…

2024年华为杯数学建模研赛 最全赛中助攻|选题建议+思路+代码+成品论文预定

2024年华为杯研究生数学建模竞赛&#xff08;以下简研赛&#xff09;将于9月21日上午8时正式开始。 下文包含&#xff1a;2024研赛思路解析​、研赛参赛时间及规则信息说明、好用的数模技巧及如何备战数学建模竞赛 C君将会第一时间发布选题建议、所有题目的思路解析、相关代码…

【2024】Benchmarking Foundation Models with Language-Model-as-an-Examiner

信息 阅读目的&#xff1a;李娟子老师团队&#xff0c;了解模型中的知识评测的工作 白雨时1*、嘉豪英2*、曹义心2、吕新1、何玉泽1, 王笑之1 、于吉凡1 、曾凯生1 、小易佳3 , Haozhe Lyu 4张嘉荫1李娟子1 , Lei Hou 1 凶 1清华大学&#xff0c;北京&#xff0c;中国2新…