今天,由于应用崩溃,服务器着火了。检查服务器后,我发现内存不断增加,这导致PM2最终终止并重新启动该过程。
这是因为我进行了修复。原始代码如下:
const cache = this.cache[script] = this.cache[script] || {};
看到我的想法之后:“当然这是一个错字,而原始创作者的意思是其他的,像这样”:
const cache = this.cache[script] || {};
通过修复一行,内存开始增长并积累,直到填满整个服务器。
我被吓死了...显然我不得不将其还原为原始版本...
这两行之间有什么区别?
答案 0 :(得分:6)
如果{}
中没有名称为变量this.cache[script]
的属性(或者存在,但其值是虚假的),则第一个将this.cache
写入script
。第二个没有。
因此,这意味着如果您多次调用此代码(或将其放在一个以上的位置),则使用第一个代码,所有这些代码最终都会共享一个对象(存储在this.cache[script]
上),但是使用第二段代码,他们都将创建并使用自己的新对象。
这就是为什么内存膨胀,代码从未缓存对象并不断创建新对象的原因。
示例:
class Example {
constructor() {
this.cache = Object.create(null);
}
getTheCache1(script) {
const cache = this.cache[script] || {};
return cache;
}
getTheCache2(script) {
const cache = this.cache[script] = this.cache[script] || {};
return cache;
}
}
const e1 = new Example();
const e1c1 = e1.getTheCache1("foo");
const e1c2 = e1.getTheCache1("foo");
console.log("e1c1 === e1c2? " + (e1c1 === e1c2));
const e2 = new Example();
const e2c1 = e1.getTheCache2("foo");
const e2c2 = e1.getTheCache2("foo");
console.log("e2c1 === e2c2? " + (e2c1 === e2c2));
或更简单的示例:
let a; // a starts out undefined
console.log("const b = a || {};");
const b = a || {};
console.log("typeof a: " + typeof a); // "typeof a: undefined"
console.log("typeof b: " + typeof b); // "typeof b: object"
console.log("a === b? " + (a === b)); // "a === b? false"
console.log("const c = a = a || {};");
const c = a = a || {};
console.log("typeof a: " + typeof a); // "typeof a: object"
console.log("typeof c: " + typeof c); // "typeof c: object"
console.log("a === c? " + (a === c)); // "a === c? true"
.as-console-wrapper {
max-height: 100% !important;
}
所有这些都有效,因为赋值的结果就是所赋的值。所以在这里:
let a, b;
b = a = a || 42;
会发生什么:
a || 42
求值,由于42
为undefined || 42
,因此得出值42
。a = <value>
,其中<value>
是步骤1的结果,因此42
被分配给a
。该表达式的结果是分配的值(42
)。b = <value>
,其中<value>
是步骤2的结果。因此42
被分配给b
。但没有其中的a =
部分:
let a, b;
b = a || 42;
只是
a || 42
求值,由于42
为undefined || 42
,因此得出值42
。b = <value>
,其中<value>
是步骤1的结果。因此42
被分配给b
。 ...保留a
不变。
答案 1 :(得分:2)
让我们添加一些括号:
const cache = (this.cache[script] = (this.cache[script] || {}));
这行代码执行两项:
this.cache[script]
(如果未定义)cache
来初始化this.cache[script]
变量结果,对cache
变量的修改也反映在this.cache[script]
内部。
备用代码将是:
cache
来初始化this.cache[script]
变量cache
变量根据上述情况,对cache
变量的修改将或不会反映在this.cache[script]
内部。
我猜测中断的代码部分取决于this.cache...
是最新的,但是使用cache
变量的代码却没有更新。