调试JavaScript堆内存不足错误的最佳步骤

时间:2019-07-04 22:14:33

标签: node.js express heap-memory

错误:

所以我得到的东西看起来像这样:

<--- Last few GCs --->

[53206:0x104800000]    14400 ms: Mark-sweep 854.6 (956.2) -> 854.6 (916.7) MB, 47.2 / 0.0 ms  (average mu = 0.871, current mu = 0.000) last resort GC in old space requested
[53206:0x104800000]    14445 ms: Mark-sweep 854.6 (916.7) -> 854.6 (915.2) MB, 44.3 / 0.0 ms  (average mu = 0.754, current mu = 0.000) last resort GC in old space requested

 <--- JS stacktrace --->

 ==== JS stack trace =========================================

     0: ExitFrame [pc: 0x32ff55ecfc7d]
 Security context: 0x04eea581d9b1 <JSObject>
     1: byteLength(aka byteLength) [0x4ee3fcd6129] [buffer.js:522] [bytecode=0x4ee55266c61 offset=204](this=0x04ee450825b1 <undefined>,0x04ee72d252e1 <Very long string[433772571]>,0x04eea587f519 <String[4]: utf8>)
     2: arguments adaptor frame: 3->2
     3: fromString(aka fromString) [0x4ee3fcef989] [buffer.js:333] [bytecode=0x4ee552620b9 offset=77](this=0x04...

 FATAL ERROR: CALL_AND_RETRY_LAST Allocation failed - JavaScript heap out of memory
  1: 0x1000645d3 node::Abort() [/usr/local/Cellar/node/11.12.0/bin/node]
  2: 0x100064c5b node::OnFatalError(char const*, char const*) [/usr/local/Cellar/node/11.12.0/bin/node]
  3: 0x10017e40f v8::Utils::ReportOOMFailure(v8::internal::Isolate*, char const*, bool) [/usr/local/Cellar/node/11.12.0/bin/node]
  4: 0x10017e3b0 v8::internal::V8::FatalProcessOutOfMemory(v8::internal::Isolate*, char const*, bool) [/usr/local/Cellar/node/11.12.0/bin/node]
  5: 0x100440714 v8::internal::Heap::UpdateSurvivalStatistics(int) [/usr/local/Cellar/node/11.12.0/bin/node]
  6: 0x10044681e v8::internal::Heap::SetUp() [/usr/local/Cellar/node/11.12.0/bin/node]
  7: 0x1004269af v8::internal::Factory::AllocateRawWithImmortalMap(int, v8::internal::PretenureFlag, v8::internal::Map*, v8::internal::AllocationAlignment) [/usr/local/Cellar/node/11.12.0/bin/node]
  8: 0x100428511 v8::internal::Factory::NewRawTwoByteString(int, v8::internal::PretenureFlag) [/usr/local/Cellar/node/11.12.0/bin/node]
  9: 0x100505f5e v8::internal::String::SlowFlatten(v8::internal::Isolate*, v8::internal::Handle<v8::internal::ConsString>, v8::internal::PretenureFlag) [/usr/local/Cellar/node/11.12.0/bin/node]
 10: 0x1001921f1 v8::String::Utf8Length(v8::Isolate*) const [/usr/local/Cellar/node/11.12.0/bin/node]
 11: 0x10004cd13 node::Buffer::(anonymous namespace)::ByteLengthUtf8(v8::FunctionCallbackInfo<v8::Value> const&) [/usr/local/Cellar/node/11.12.0/bin/node]
 12: 0x1001e2ac4 v8::internal::FunctionCallbackArguments::Call(v8::internal::CallHandlerInfo*) [/usr/local/Cellar/node/11.12.0/bin/node]
 13: 0x1001e2124 v8::internal::MaybeHandle<v8::internal::Object> v8::internal::(anonymous namespace)::HandleApiCallHelper<false>(v8::internal::Isolate*, v8::internal::Handle<v8::internal::HeapObject>, v8::internal::Handle<v8::internal::HeapObject>, v8::internal::Handle<v8::internal::FunctionTemplateInfo>, v8::internal::Handle<v8::internal::Object>, v8::internal::BuiltinArguments) [/usr/local/Cellar/node/11.12.0/bin/node]
 14: 0x1001e1944 v8::internal::Builtin_Impl_HandleApiCall(v8::internal::BuiltinArguments, v8::internal::Isolate*) [/usr/local/Cellar/node/11.12.0/bin/node]
 15: 0x32ff55ecfc7d

,我绝对不知道如何开始调试它。我研究过类似的问题“ Javascript堆内存不足”,并了解可以增加内存限制(接缝是最常见的建议解决方案)。


代码

引起错误的函数是一个看起来像这样的Express控制器(简化):

const foo = async (req,res) => {
   // get users in chat room
   const users = await db.getUsers(req.query.roomId);
   res.send(users);
}

当我向房间添加另一个用户时出现错误。我还检查了如果我过滤掉最后添加的用户,该错误消失了。从打印调试中,我还看到所有代码都执行到res.send语句为止,因此似乎该函数中发生了错误。


问题

我不愿意增加内存的原因是我只是将问题推到更远的位置,而不是崩溃时出现6个用户,而是崩溃了15个或30个用户。

因此,我想调试该脚本(也许看看users对象占用了多少内存,以及不同形式的优化对其有何影响。

我根本不知道如何调试这些低级错误,不知道遇到这种错误时是否可以通过一些标准?


PS:刚发现最上面建议的类似问题是:

How to create an HTML button that acts like a link?

0 个答案:

没有答案