如何判断promise对象是否被回收?

1个回答

写回答

13694611112

2026-02-17 10:18

+ 关注

JS
JS

前几年答过这问题,现在再重新答一次。想知道promise对象是否已被回收,可在控制台使用queryObjects()。

queryObjects(Promise)的作用是先手动进行一次垃圾回收,接着输出当前页面内存中仍然存在的promise对象。若数量为0,则表明所有的promise对象均已被回收。要更清晰地看到回收确实发生了,我们还能给传入test()的promise对象以及test()返回的promise对象都加上垃圾回收的回调。

能够发现,这两万个永远不会得到解决(resolve)的承诺(promise)都已被回收,这是在预期之内的。JS标准或许未规定垃圾回收的具体细节。不管是对象何时被回收,还是完全不回收,可能都不算违反规范,毕竟test262中无相关测试。但在制定规范时,从逻辑上讲肯定还是要考虑避免内存泄漏的。这些都是引擎实现方面的知识,只有少数引擎开发者能讲清细节,我只略知一二,下面是我的推测。对象若不被回收,就得有引用之处,除直接引用外,也可间接引用,例如:全局变量foo引用了resolve函数,该函数较为特殊,在C++层面实际引用了其所属的promise对象,这会使promise对象一直处于可达状态,从而无法被垃圾回收。就像这个promise,要10秒后才会被垃圾回收。在这10秒内,全局任务队列里有个定时器任务对它有引用,等定时器执行完并销毁后,该promise对象就无法被访问,于是就会被回收了。若resolve与reject均未被引用,那它会被直接回收。除非有其他引用,如示例中的p。

C++
C++

其实在V8里,async function在解析(parser)阶段会被脱糖(desugar)成generator,详见Google.com/document/d/1K38ct2dsxG_9OfmgErvFld4MPDC4Wkr8tPuqmSWu_3Y/edit">https://docs.Google.com/document/d/1K38ct2dsxG_9OfmgErvFld4MPDC4Wkr8tPuqmSWu_3Y/edit。因此,test函数在实际执行的时候可能是这样的:生成器在yield p处停住,这和awAIt p停住类似。由于无法再引用生成器的next()方法,引擎便知道它不能继续执行了,于是就把所有相关对象一连串回收掉,具体细节我也说不明白。

举报有用(12分享收藏

Copyright © 2025 IZhiDa.com All Rights Reserved.

知答 版权所有 粤ICP备2023042255号