我有一个节点js应用程序,它使用sharp对大文件进行一些图像处理,后者又使用nan与节点进行交互。当我加载一个非常大的图像时,我得到一个来自nan的错误
node: ../node_modules/nan/nan.h:679: Nan::MaybeLocal<v8::Object> Nan::NewBuffer(char*, size_t, node::Buffer::FreeCallback, void*): Assertion `length <= imp::kMaxLength && "too large buffer"' failed.
Aborted (core dumped)
但总的来说,它说:
// arbitrary buffer lengths requires
// NODE_MODULE_VERSION >= IOJS_3_0_MODULE_VERSION
assert(length <= imp::kMaxLength && "too large buffer");
我有
$ node -v
v4.4.6
您在top of the file看到的版本应该是IOJS_3_0_MODULE_VERSION
以后的版本,提供任意长度的缓冲区。但是,断言不被#ifdef
包围。有没有人知道如何在使用nan时使用任意长度的缓冲区?
答案 0 :(得分:1)
NAN维护者希望在所有版本的节点上提供统一的行为,这似乎意味着坚持早期版本的节点(discussion)的限制。我假设为什么周围没有#ifdef
可以为新版本启用大缓冲区。
如果你在不使用NAN的情况下为缓冲区分配内存,那么你可以达到0x7fffffff
的当前kMaxLength(即超过NAN限制它的额外千兆字节)。
size_t len = 0x7fffffff;
char* bigbuf = (char*)malloc(len);
node::Buffer::New(v8::Isolate::GetCurrent(), bigbuf, len);
我不确定你在管道中的哪个位置 - 你是否正在从磁盘读取?其中一些技术可能很有用:
从文件块中读取数据。 kMaxLength
是最大索引,而不是可以使用的最大内存量。因此,如果您可以从C ++或流数据处理程序(使用typedarray.set
)将大缓冲区读入更宽的TypedArray,那么您可以返回例如一个0x7fffffff
- 长度的Uint32Array消耗8,589,934,588字节。
// Not tested
var fs = require("fs");
var path = "/path/to/file";
var size = fs.statSync(path).size;
var dest = new Uint32Array(size / Uint32Array.BYTES_PER_ELEMENT);
var destOffset = 0;
var rs = fs.createReadStream(path);
rs.on("data", function (chunk) {
var hunk = new Uint32Array(chunk.buffer, chunk.byteOffset, b.byteLength);
dest.set(hunk, destOffset);
destOffset += hunk.length;
});