vuejs 应用程序中无法检测到的内存泄漏

Posted

技术标签:

【中文标题】vuejs 应用程序中无法检测到的内存泄漏【英文标题】:Undetectable memory leak in vuejs application 【发布时间】:2017-11-02 10:20:16 【问题描述】:

我已经尝试解决这个问题一段时间了,我什至尝试重写整个程序但没有成功。该应用程序在 VueJS 2.3.3 上运行,并且应该结合 Raspberry Pi 在 Chromium 上运行(暂时不相关信息)。

我们正在处理包含在单个文件中的多个组件,稍后将使用gulpnpm run dev 编译此文件。当VueJS 的实例初始化时,将使用Vue Resource$http 选项发送请求。这将收到一个大小约为30mb 的json 响应。这将保存在数据数组中,如下所示:

this.$http.get('<url>' + this.token)
    .then((response) => 
        this.properties = response.properties;
    );

这些数据稍后将用于进一步的操作,另一件值得一提的是数据每隔一段时间就会刷新一次。这就是我认为问题发生的地方,如果我不是每 5 分钟刷新一次数据(也可以更长,真的取决于我测试的方式),程序运行良好。只是我想每隔一段时间刷新一次数据以检索新信息。我正在使用的设置超时的方式如下:

this.dataTimeout = setTimeout(this.refreshData, 300000); 

每个(所谓的)property 至少有 6 个 base64 图像保存在它的 JSON 中,这些图像稍后用于呈现给用户。除此之外,还有名称、地址和其他一些微小的数据。听起来并没有那么错,但我感觉每个响应都会使内存变得如此密集,以至于即使是台式机也无法运行它。

每 10 秒,用户屏幕上会显示一个新的property,包括图像、街道、位置等。我不确定我的代码中是否存在内存泄漏或者我是否忘记了什么。我的脑海里突然冒出几个问题:

    我是否需要将我从服务器获得的响应重置回 nullundefined? 我正在使用的插件之一(仅 VueResources)是否存在泄漏? VueJS 实例可以存活多长时间,是否有建议的时间来重新加载整个程序? 为了实现这一目标,我应该考虑什么?

我已经把数据更新拿出来放了一个demo项目上线,这个可以看here。我遇到的主要问题是浏览器内存不足,并向我们展示了来自 Chrome 的惊人的Aw snap! 页面。我尝试从内存使用情况中拍摄快照,但一切似乎都很好,只是在一段时间后随机爆炸。

提前致谢!

【问题讨论】:

我不知何故遇到了完全相同的问题。我在树莓派 3 / 4 上的 chromium 浏览器中运行 vue 应用程序,似乎 chromium-browser(还有电子)无法释放未使用的内存,甚至在几小时内填满内存(取决于内容)并导致“aw snap!” .我无法在应用程序本身中看到任何内存泄漏。唯一有助于释放内存的方法是关闭并重新启动 chromium。 【参考方案1】:

好吧,我不知道您的应用程序真正的用途是什么,但是您的 30Mb 数据真的有用/必不可少吗?还在 JSON 中?

也许您不需要所有这些数据,您可以根据需要调整数据。例如,保留您的 JSON 存储数据,并通过其他方式检索您的 Base64 图像。

我不明白您为什么将图像存储在内存中。在我看来,图像只是用于显示目的。

所以我认为 30Mb 真的很大。但也许我错了?

顺便说一句,我已经用 Firefox Nightly 进行了测试,这里没有问题。似乎没有崩溃。也许我没有遇到刷新调用?

【讨论】:

在线版本的刷新已经关闭,以展示我们正在做的事情。我们将图像作为 base64 保存在 json 中,这样只要计算机没有互联网,图像仍然可以显示。并且 30mb 仍然很小,应用程序中的某些步骤大约有 720 个图像。总计数百 mbs .. 我们尝试将它们存储在本地存储中,但我们无法在 Pi 上分配正确的大小。我会打开数据刷新并上传它,当它在线时我会提醒你。 :) 我已经打开了,这次不切换幻灯片了。下载完成后 10 秒刷新数据。目前大小约为 38.5mb,我也在生产模式下运行 gulp。 嗯,实际上每次刷新都会增加内存消耗。我目前是 420 MB。对于这样的网络应用来说太多了。我认为你必须尽量不在 VueJS 反应系统中存储图像。 我们必须将它们存储在哪里,知道吗?我尝试了本地存储,但没有成功。甚至尝试了本地 sql 存储,但最终负载也太大了。 好吧,因为我不确定你想对所有这些文件做什么,我只能说将二进制数据集成到 Vue 反应系统中不是一个好主意......如果你想在使用之前“预取”图像,我认为你可以做不同的事情。例如通过插入带有display:none css 规则的&lt;img&gt; 元素?如果您想将这些文件存储到离线状态,那么您不知道该怎么做,因为我不知道您的文件是否取决于用户?也许去developer.mozilla.org/en-US/docs/Web/API/Service_Worker_API/…

以上是关于vuejs 应用程序中无法检测到的内存泄漏的主要内容,如果未能解决你的问题,请参考以下文章

discord.js 如何将检测到的内存泄漏发送到通道?

泄漏消毒剂检测泄漏

什么是内存泄漏?

无法使用 VS2008 内存泄漏检测器

Tomcat如何检测内存泄漏

SearchView在Android应用中泄漏内存