我有一个监听器附加到Firebase密钥,该密钥接受更改,通过我的处理运行它,然后使用结果更新Firebase密钥。代码如下所示:
db.child(key).on('child_added', (snap) => {
processing(snap.val())
.then([snapKey, obj] => db.child(snapKey).update(obj))
});
但是,当我注意到每次在Firebase密钥上调用更新时,内存使用量会泄漏几兆字节,这是不可接受的。
当我使用来自memwatch-next
的探测时,这就是我的代码:
db.child(key).on('child_added', (snap) => {
processing(snap.val())
.then([snapKey, firebaseObj]) => {
return new Promise((res) => {
hd = new memwatch.HeapDiff();
db.child(key).child(snapKey).update(firebaseObj, () => {
res(hd);
})
})
})
.then((hd) => {
console.log(hd.end());
})
});
这是我运行代码时console.log(hd.end())
行返回的几次迭代(每次迭代都在添加的每个子节点中):
{ before: { nodes: 146168, size_bytes: 17594735, size: '16.78 mb' },
after: { nodes: 176255, size_bytes: 19080111, size: '18.2 mb' },
change:
{ size_bytes: 1485376,
size: '1.42 mb',
freed_nodes: 5187,
allocated_nodes: 35274,
details:
[ [Object],
...
[Object] ] } }
{ before: { nodes: 178862, size_bytes: 19198176, size: '18.31 mb' },
after: { nodes: 212089, size_bytes: 20877626, size: '19.91 mb' },
change:
{ size_bytes: 1679450,
size: '1.6 mb',
freed_nodes: 1471,
allocated_nodes: 34699,
details:
[ [Object],
...
[Object] ] } }
{ before: { nodes: 214254, size_bytes: 20919620, size: '19.95 mb' },
after: { nodes: 247320, size_bytes: 22549300, size: '21.5 mb' },
change:
{ size_bytes: 1629680,
size: '1.55 mb',
freed_nodes: 1404,
allocated_nodes: 34471,
details:
[ [Object],
...
[Object] ] } }
{ before: { nodes: 249507, size_bytes: 22614374, size: '21.57 mb' },
after: { nodes: 282578, size_bytes: 24219130, size: '23.1 mb' },
change:
{ size_bytes: 1604756,
size: '1.53 mb',
freed_nodes: 1390,
allocated_nodes: 34462,
details:
[ [Object],
...
[Object] ] } }
{ before: { nodes: 284930, size_bytes: 24329463, size: '23.2 mb' },
after: { nodes: 317934, size_bytes: 25917780, size: '24.72 mb' },
change:
{ size_bytes: 1588317,
size: '1.51 mb',
freed_nodes: 1400,
allocated_nodes: 34405,
details:
[ [Object],
...
[Object] ] } }
由于这种泄漏,在运行我的节点应用程序时,我遇到了这个错误:
Error: spawn ENOMEM
at _errnoException (util.js:999:13)
at ChildProcess.spawn (internal/child_process.js:340:11)
at exports.spawn (child_process.js:499:9)
at Object.exports.fork (child_process.js:100:10)
at rateLimit (/home/deploy/amNewBack/releases/20180104233801/index.js:118:33)
at ChildProcess.n.on
(/home/deploy/amNewBack/releases/20180104233801/index.js:143:15)
at ChildProcess.emit (events.js:159:13)
at emit (internal/child_process.js:790:12)
at process._tickCallback (internal/process/next_tick.js:152:19)
FATAL ERROR: Committing semi space failed. Allocation failed - process out of
memory
1: node::Abort() [/usr/local/bin/node]
2: 0x11ef43c [/usr/local/bin/node]
3: v8::Utils::ReportOOMFailure(char const*, bool) [/usr/local/bin/node]
4: v8::internal::V8::FatalProcessOutOfMemory(char const*, bool)
[/usr/local/bin/node]
5:
v8::internal::Heap::PerformGarbageCollection(v8::internal::GarbageCollector,
v8::GCCallbackFlags) [/usr/local/bin/node]
6: v8::internal::Heap::CollectGarbage(v8::internal::AllocationSpace,
v8::internal::GarbageCollectionReason, v8::GCCallbackFlags)
[/usr/local/bin/node]
7: v8::internal::Factory::NewRawTwoByteString(int,
v8::internal::PretenureFlag)
[/usr/local/bin/node]
8: v8::internal::Factory::NewStringFromUtf8(v8::internal::Vector<char const>,
v8::internal::PretenureFlag) [/usr/local/bin/node]
9: v8::String::NewFromUtf8(v8::Isolate*, char const*, v8::NewStringType, int)
[/usr/local/bin/node]
10: node::StringBytes::Encode(v8::Isolate*, char const*, unsigned long,
node::encoding, v8::Local<v8::Value>*) [/usr/local/bin/node]
11: 0x120b762 [/usr/local/bin/node]
12: v8::internal::FunctionCallbackArguments::Call(void (*)
(v8::FunctionCallbackInfo<v8::Value> const&)) [/usr/local/bin/node]
13: 0xb7c08c [/usr/local/bin/node]
14: v8::internal::Builtin_HandleApiCall(int, v8::internal::Object**,
v8::internal::Isolate*) [/usr/local/bin/node]
15: 0x326bb34842fd
FATAL ERROR: Deoptimizer::EnsureCodeForDeoptimizationEntry Allocation failed -
process out of memory
1: node::Abort() [/usr/local/bin/node]
2: 0x11ef43c [/usr/local/bin/node]
3: v8::Utils::ReportOOMFailure(char const*, bool) [/usr/local/bin/node]
4: v8::internal::V8::FatalProcessOutOfMemory(char const*, bool)
[/usr/local/bin/node]
5:v8::internal::Deoptimizer::EnsureCodeForDeoptimizationEntry
(v8::internal::Isolate*, v8::internal::Deoptimizer::BailoutType, int)
[/usr/local/bin/node]
6: v8::internal::Deoptimizer::EnsureCodeForMaxDeoptimizationEntries
(v8::internal::Isolate*) [/usr/local/bin/node]
7: v8::internal::compiler::PipelineCompilationJob::PrepareJobImpl()
[/usr/local/bin/node]
8: v8::internal::CompilationJob::PrepareJob() [/usr/local/bin/node]
9: 0xd9a7af [/usr/local/bin/node]
10: v8::internal::Compiler::CompileOptimized
(v8::internal::Handle<v8::internal::JSFunction>,
v8::internal::ConcurrencyMode) [/usr/local/bin/node]
11: v8::internal::Runtime_CompileOptimized_Concurrent(int,
v8::internal::Object**, v8::internal::Isolate*) [/usr/local/bin/node]
12: 0x1e20022042fd
错误本身是在processing()
期间我的节点处理分叉时导致的,但是,根据memwatch-next
的结果,Firebase更新步骤中会出现内存丢失。这是Firebase中的一个现有错误吗?