NodeJS闭包引用判定与内存泄漏相关技术问题咨询
闭包与垃圾回收相关问题解答
我知道闭包里如果有对象引用,能让对象躲过GC回收。现在有几个具体问题要明确:
1. 闭包中的“引用”仅指赋值给变量吗?调用/获取属性算不算?
结论是:只要内部函数的代码里直接用到了外部的someObject,不管是读取属性、调用方法还是直接赋值引用,都会让闭包持有这个对象的引用,阻止它被GC回收。
结合你给出的代码逐个分析:
const someObject = { myProp: 123, callable: () => console.log('hello!') } function outer() { const innerAssign = () => { const innerVar = someObject.myProp; // 会创建闭包引用! // 要访问myProp必须先拿到someObject的引用,JS引擎会把该对象纳入闭包捕获范围 } const innerCall = () => { someObject.callable(); // 会创建闭包引用! // 调用callable方法前必须获取someObject的引用,闭包会保留这个引用 } const innerRef = () => { const newRef = someObject; // 肯定会创建闭包引用,逻辑最直接 } }
简单来说,只要内部函数的执行依赖someObject的存在,JS引擎就会把该对象留在闭包的依赖链里,避免被GC回收。
2. Object.keys会生成对原对象的引用吗?
不会。Object.keys(someObject)返回的是独立的字符串数组,里面只存了对象属性名的副本,和原对象没有引用关联。执行完这个方法后,只要原对象没有其他存活引用,GC就可以正常回收它,不受返回的keys数组影响。
3. 给已有对象创建新引用,会在堆上分配额外内存吗?
不会。对象本身存储在堆内存中,所谓“引用”只是栈内存(或作用域存储)里的一个指针,指向堆中对象的地址。创建新引用只是多了一个极小的指针(比如64位系统占8字节),不会给原对象分配新的堆内存——原对象还是同一个,只是多了一个指向它的“标记”而已。
内容的提问来源于stack exchange,提问作者jjordan
相关产品推荐
相关产品推荐

