【问题标题】:Are global variables cleaned by garbage collector in Node?Node中的垃圾收集器是否清理了全局变量?
【发布时间】:2019-06-15 20:00:15
【问题描述】:

在下面的 JS 代码中,example1example2 是否会被垃圾收集器清除?他们的内存会被 GC 释放吗?我正在处理内存泄漏,我的代码中有一些这样的实例。

example1 = 'Outside a function'

function sample(x){
    example2 = 'Inside a function'
}
sample(1)

据我了解,垃圾收集器不会清除这两个变量,因为它们被视为全局变量。可能听起来像一个微不足道的问题,但发现内存泄漏就像大海捞针

【问题讨论】:

  • 您的问题不清楚。垃圾收集器不会清除变量。你能澄清一下你的意思吗?
  • @JörgWMittag 做了一些修改,这样更有意义吗?
  • 并非如此。就像我写的:垃圾收集器不会清理变量。因此,不清楚您所说的“在以下 JS 代码中,example1example2 是否会被垃圾收集器清理?”和“垃圾收集器永远不会清理任何变量”。
  • 首先,停止使用未在某个范围内显式声明的变量。这只是一种不好的做法,如果您按照应有的方式运行严格模式,它甚至会是一个错误。重复 - 不好的做法。使用varletconst 显式声明所需范围内的每个变量。仅当任何仍在运行的代码无法再访问该变量时,垃圾收集器才会清理任何范围内的变量的内容。因此,如果某些代码仍然可以访问您的变量,那么垃圾收集器将不会清理该变量的内容。
  • 攻击内存泄漏的常用方法是记录堆快照,然后比较它们以找出两个快照之间的差异,看看这是否是您所期望的,或者是否有一些东西似乎在不断累积。这是 nodejs 中的how to do that

标签: javascript node.js memory-leaks


【解决方案1】:

堆有两个主要段,新空间和旧空间。新空间是发生新分配的地方;在这里收集垃圾很快,大小约为 1-8MB。生活在新空间中的对象称为年轻一代。在新空间的收集器中幸存下来的对象被提升到旧空间 - 它们被称为老一代。 Old Space 中的分配速度很快,但收集成本很高,因此很少执行。

你需要了解一些想法,例如:

1 - 垃圾收集器构建“根”列表。根通常是在代码中保存引用的全局变量。在 JavaScript 中,“window”对象是可以充当根的全局变量的一个示例。窗口对象始终存在,因此垃圾收集器可以认为它及其所有子对象始终存在(即不是垃圾)。

2 - 检查所有根并将其标记为活动(即不是垃圾)。所有的孩子也被递归地检查。从根可以到达的所有东西都不会被视为垃圾。

3- 所有未标记为活动的内存现在都可以被视为垃圾。收集器现在可以释放该内存并将其返回给操作系统。

关于你的问题:

From what I understand is neither of the variables will ever be cleaned by Garbage collector because they are treated as global variables. 
Might sound like a trivial question but finding memory leaks is like finding a needle in a haystack

你是对的。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-02-21
    • 2011-05-07
    • 1970-01-01
    • 1970-01-01
    • 2015-04-10
    相关资源
    最近更新 更多