【发布时间】:2015-08-06 13:14:14
【问题描述】:
我是 node Js 的新手,我已经构建了一个非常简单的服务器,可以将我请求的 zip 文件发回给我。一切正常,但在某些请求发生崩溃后,我在终端上看到了这条消息:
致命错误:node::smalloc::Alloc(v8::Handle, size_t, v8::ExternalArrayType) 内存不足
var http = require('http');
var url = require('url');
var fs = require('fs');
var port = 1337;
// create http server
var server = http.createServer(function (request, response) {
var path = require('url').parse(request.url, true);
console.log('requested ' + path.pathname);
//get zipped resoures
if (path.pathname == '/getzip') {
console.log(request.url);
var queryData = url.parse(request.url, true).query;
if (queryData.name) {
var filename = queryData.name;
//open corrisponding file
var zipFile = fs.readFileSync('packets/' + filename);
response.writeHead(200, {
'Content-Type': 'application/x-zip',
'Content-disposition': 'attachment; filename=data.zip'
});
//send file in response
response.end(zipFile);
}
else {
response.writeHead(200, {'Content-Type': 'text/plain'});
response.end('{error = "bad url"}');
}
}
}).listen(port);
server.timeout = 1000000;
你知道它是什么吗?这段代码看起来很简单。
【问题讨论】:
-
您的 zip 文件有多大?你能确定哪一行导致分配错误吗?我的建议是在 readFileSync 和 response.end() 周围放置一些输出,以查看是否是导致它的行。如果您有很多大文件,这可能真的是内存不足的问题。
-
另外,不要总是信任节点的垃圾收集器。可能是您的响应对象不是 gc'd,所以您可能想说 response = null;在你的函数结束时确保它不会徘徊。不应该是这样,但您可能还是想尝试一下。
-
最大的 zip 是 500 mb;它很大,但我在 16GB 内存机器上运行脚本。感谢您的回答,我现在做一些测试。
-
崩溃发生在 readFileSync 中(我使用日志检查它,如你所说)我去检查内存,如果问题是 zip 太大,你有一些建议将其发送为节点中有多个数据包?
-
您可以分块阅读。您可以使用 fs.open() 获取文件指针并在其上使用 fs.read(使用 position=null,从您离开的地方继续读取)。检查函数的返回值并读取它直到它为 0,使用 .write() 将块保存到响应中(我想,看看 API)。但如果是内存泄漏问题,那就无济于事了。如果文件对于 readSync 来说太大,它将起作用(也许系统不允许您一次分配 500 多兆字节的内存,我从未尝试过 :))
标签: javascript node.js fatal-error alloc