繁体   English   中英

递归setTimeout调用会导致闭合链内存泄漏吗?

[英]Does a recursive setTimeout call cause a closure chain memory leak?

我有以下情况:

 let func = () => { //... let id = setTimeout(() => { console.trace(); clearTimeout(id); func(); }, 2000); } func(); 

例如,如果我们在Chrome控制台中运行以下代码,则会得到以下堆栈跟踪

console.trace
(anonymous) @ VM89644:4
setTimeout (async)
func @ VM89644:3
(anonymous) @ VM89644:6
setTimeout (async)
func @ VM89644:3
(anonymous) @ VM89644:6
setTimeout (async)
func @ VM89644:3
(anonymous) @ VM89644:6
setTimeout (async)
func @ VM89644:3
(anonymous) @ VM89644:6
setTimeout (async)
func @ VM89644:3
(anonymous) @ VM89644:6
setTimeout (async)
func @ VM89644:3
(anonymous) @ VM89644:6
...
...
...

每次迭代都会增加。 最终,它达到了一个最高点(我认为在35次迭代之后),该链似乎停止增长了,但是我很好奇它是否只是Chrome而不显示它。 到底是什么情况?

递归setTimeout调用会导致闭合链内存泄漏吗?

不会。每次触发计时器后,浏览器中的计时器子系统都会释放其与计时器功能的链接,而该链接又会将其链接释放至创建该计时器的环境,从而允许它们都被回收。

每次迭代都会增加。 最终,它达到了一个最高点(我认为在35次迭代之后),该链似乎停止增长了,但是我很好奇它是否只是Chrome而不显示它。 到底是什么情况?

这是标准的内存管理,根据JavaScript引擎对内存管理的启发式方法来清理事物,而这些启发式方法并不总是主动地清理事物。 我怀疑如果您反复按一下devtools的“收集垃圾”按钮(在“内存”选项卡上),您会发现它回到了接近基线的水平。

V8的漂亮异步堆栈跟踪可能会阻止返回到接近基线的一件事。 它们被宣传为“零成本”,但是当然,这不可能完全正确,因为它们必须跟踪异步堆栈信息(即使只是字符串)。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM