全局数组中的对象没有被释放(垃圾回收)

问题描述 投票:0回答:1

关于垃圾收集的问题。

我有一个 javascript 程序,其中有一个在 Application.js 中初始化的全局变量

let g_objArr = []
。此
g_objArr
用于加载客户个人资料详细信息。该数组包含一堆详细说明客户资料的对象。 (例如:
[ {name: {first:John}, {last:Doe}}, {Address: {street: {5th street}, apartment: null}.., {...}] 

我在各种地方使用这个

g_objArr
。但在某些时候,当在功能中选择另一个客户配置文件时,它会被重置并重新加载
loadCustomerDetails()
。如果选择了新客户,此函数将加载新的客户配置文件;如果再次选择同一客户,则该函数不执行任何操作并返回当前客户。基本上,它会分配
g_objArr = //some new array thats loaded from an api call

问题是我的程序使用了太多内存。每个

g_objArr
都很大,好像加载新客户时,老客户的内存还保留着,所以内存不断增长。

我最初的解决方案是设置

g_objArr.length = 0
,它似乎可以清除数组并销毁对数组中对象的引用。

但是,我的队友说我应该查看数组中对象的悬空引用在哪里,如果删除了这些悬空引用,那么垃圾收集器应该清除数组本身,而无需我显式设置 length = 0 .

使用数组的地方很多,需要时间梳理一下。经过初步检查,我没有看到任何可以保留悬空引用的地方(例如,有一些使用它的 for 循环,但我认为一旦循环结束/函数退出就无关紧要)

我的问题是,我的队友正确吗?或者事实上

g_objArr
是一个全局意味着对数组中对象的引用永远不会被清除,除非明确这样做(长度 = 0 方法)。

非常感谢!

额外:该应用程序不是托管在网络上,而是托管在 vscode 上。不确定那里是否有内存分析工具。

javascript memory memory-leaks garbage-collection global-variables
1个回答
0
投票

V8

快速搜索后发现 vscode 是一个电子应用程序,它使用 Nodejs 和 V8 JavaScript 引擎。如果您想自行搜索以确认结果,请这样做。

GC

JavaScript 中的内存垃圾收集基于堆上存储的数据是否可以通过代码访问,这与保存对堆上数据的引用并不完全一样。全局变量肯定是“可访问的”,并且不会被 gc 仅仅因为

当前代码中没有其他引用它。 GC也是由JS引擎自动进行的。它可以通过调用 global.gc

在节点中手动触发,但这需要使用

--expose-gc

 标志在节点配置中公开。 
也许可以
在启动时配置 vscode 以通过附加配置启动节点,但这不是我个人可以确认的。
悬挂参考文献

在部分代码中复制 g_objArr

的值有可能减少可用堆空间量:

const userData = g_objArr;

创建对当前保存在
g_objArr
中的数组的引用。如果更新

g_objArr

,则 
userData
 现在不再需要以前的值。如果仍然可达,则在再次执行对 
userData
 的赋值之前不会对其进行 gc。如果这是在多个地方完成的,并且在
not
为每个用户执行的代码中,那么它很可能会影响可用的堆空间。
类似的注意事项适用于保存对数组条目的引用,或调用 Array

方法(例如

slice

)的结果,这些方法创建单个用户数据的全部或部分克隆副本。
如果这是您的队友寻找悬空参考的目的,那么您应该这样做。无论如何你应该这样做:-)

© www.soinside.com 2019 - 2024. All rights reserved.