Node.js Nodejs内存管理

Node.js Nodejs内存管理,node.js,memory-management,memory-leaks,garbage-collection,Node.js,Memory Management,Memory Leaks,Garbage Collection,我开始学习Nodejs并试图理解它管理内存的方式。 我知道有一种东西叫做“GC”(垃圾收集器) 我尝试使用Express JS编写以下小代码: const express = require('express') const app = express() const port = 3000 app.get('/', (req, res) => { res.send('Hello World!') let used = process.memoryUsage().heap

我开始学习Nodejs并试图理解它管理内存的方式。 我知道有一种东西叫做“GC”(垃圾收集器)

我尝试使用Express JS编写以下小代码:

const express = require('express')
const app = express()
const port = 3000

app.get('/', (req, res) => {
    res.send('Hello World!')
    let used = process.memoryUsage().heapUsed / 1024 / 1024;
    console.log(`The script uses approximately ${Math.round(used * 100) / 100} MB`);
})
app.get('/a', (req, res) => {
    var array = Array(1e7).fill("a");
    delete array;
    let used = process.memoryUsage().heapUsed / 1024 / 1024;
    console.log(`The script uses approximately ${Math.round(used * 100) / 100} MB`);

    res.send('Hello World!')
})
app.listen(port, () => {
    console.log(`Example app listening at http://localhost:${port}`)
})
我增加了两条路线。 第一条路径没有什么特别的,只是一段代码,用来打印内存使用量

在第二条路径中,我创建了一个巨大的数组,然后删除它

我叫第一条路线。我得到:

脚本使用大约5.87 MB

然后我呼叫第二条路线,我得到:

脚本大约使用82.2MB

然后我刷新第一条路线,我得到:

脚本大约使用4.36 MB

然后我再次刷新第二条路线。我得到:

该脚本使用大约80.6MB

从现在起,无论我刷新第一条路线多少次,我都会得到:

脚本使用大约80.65 MB

我知道“delete”关键字只会破坏引用,并不能立即释放内存

但是GC呢?它在做什么? 我等待了10多分钟,尝试了第一条路线,结果几乎相同(>80MB)

有人能解释为什么记忆没有减少吗?
感谢您的帮助

大型对象总是属于“垃圾收集”的第2代,这就是为什么即使没有引用,此类对象也比小型对象“存活”更长的原因


除了
删除数组
您可以执行
array.length=0之前。

大型对象总是属于“垃圾收集”的第2代,这就是为什么即使没有引用,此类对象也比小型对象“存活”更长的原因



除了
删除数组
您可以执行
array.length=0预先删除。

删除
用于从对象中删除属性。它不是用来删除局部变量的-它不是这样做的。。请参阅此以了解详细信息。如果希望数组符合垃圾收集的条件,请将局部变量设置为
null
。@jfriend00当函数完成执行并清除堆栈帧时,该数组无论如何都应该是可GC的,因为它没有在其他任何地方被引用。@VLAZ-是的,这不是这个问题的内容。OP试图测量即时内存使用量的变化,这种变化在
delete
或将其设置为
null
时不会发生,因为GC不是这样工作的。我以前的注释末尾应该有“立即”一词,但遗憾的是,我不能再编辑该注释了。@jfriend00场景是,最终调用了第一条路由,但堆内存似乎仍被数组使用,该数组仅在处理第二条路由时才存在。如果它在2小时内仍然存在,这可能是一个度量问题,而不是内存使用问题。内存可能仍属于进程,但可用于恢复。如果在两次请求之间间隔几秒钟运行同一请求1000次,服务器内存使用是否会在每次请求时不断增加,并在完成所有操作后保持非常高的使用率。
delete
用于从对象中删除属性。它不是用来删除局部变量的-它不是这样做的。。请参阅此以了解详细信息。如果希望数组符合垃圾收集的条件,请将局部变量设置为
null
。@jfriend00当函数完成执行并清除堆栈帧时,该数组无论如何都应该是可GC的,因为它没有在其他任何地方被引用。@VLAZ-是的,这不是这个问题的内容。OP试图测量即时内存使用量的变化,这种变化在
delete
或将其设置为
null
时不会发生,因为GC不是这样工作的。我以前的注释末尾应该有“立即”一词,但遗憾的是,我不能再编辑该注释了。@jfriend00场景是,最终调用了第一条路由,但堆内存似乎仍被数组使用,该数组仅在处理第二条路由时才存在。如果它在2小时内仍然存在,这可能是一个度量问题,而不是内存使用问题。内存可能仍属于进程,但可用于恢复。如果在两次请求之间间隔几秒钟运行同一个请求1000次,服务器内存使用是否会在每次请求时不断增加,并在完成所有操作后保持非常高的使用率。
array=null
会更好<代码>删除数组
根本不删除局部变量<代码>删除
用于从对象中删除属性,而不是删除局部变量
delete
在本例中无法尝试释放局部变量使用的内存。对于局部变量,通常无需执行任何操作(如果它们不存储非托管资源)。同意,无需执行任何操作。那么,为什么您要说“除了
删除数组;
之外,您还可以执行
array.length=0;
”?当第一个什么都不做,第二个在这里是不需要的。最终,这个问题需要通过深入研究垃圾收集的时间以及
process.memoryUsage().heapUsed
报告来解释。这个问题的答案绝对与
delete array
array.length=0
有关。这就是我的观点。我只是忘记了无用的
delete somevar
。我的错。我只是认为
array.length=0
可以帮助更快地释放内存。@jfriend00正如我在问题中提到的,我知道
delete
不能立即释放内存。我也尝试了
array=null
。但我的问题是,为什么这个未使用的变量会存在很长时间?为什么GD不收集它?
array=null
会更好<代码>删除数组根本不删除局部变量<代码>删除用于删除pro