【问题标题】:memory error in node JS (node::smalloc::Alloc)节点 JS 中的内存错误 (node::smalloc::Alloc)
【发布时间】: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


【解决方案1】:

您应该利用streams,而不是将整个文件读入内存:

response.writeHead(200, {
  'Content-Type'        : 'application/x-zip',
  'Content-disposition' : 'attachment; filename=data.zip'
});
fs.createReadStream('packets/' + filename).pipe(response);

【讨论】:

    猜你喜欢
    • 2013-09-11
    • 2017-12-06
    • 2023-03-10
    • 2015-10-18
    • 2014-10-05
    • 2017-11-21
    • 2019-06-19
    • 2012-02-21
    • 1970-01-01
    相关资源
    最近更新 更多