首页 > 解决方案 > 大量 postMessages 后 nodejs webworker-threads 崩溃

问题描述

在向 webworker 发送大量 postMessages 之后,我得到了一个中止和堆栈跟踪,如下面的原始问题所示。我将间隔从 250 毫秒减少到 6 毫秒,然后这个问题出现得更早,大约 45 分钟而不是 6-9 小时。

代码相当简单

mainapp.js

const Worker = require('webworker-threads').Worker;
var myappwebworker = new Worker('./myappwebworker.js');
myappwebworker.addEventListener('message', function(e) {
  console.log(e)
});
setInterval(function() {  
  myappwebworker.postMessage('hello');
}, 250); // or 5 for abort in about 45min

myappwebworker.js

self.addEventListener('message', function(e) {
  self.postMessage('You said: ' + e.data);
}, false);

这是什么原因?我是否因为垃圾收集器没有时间运行或类似的东西而用完堆?无论如何,可以做些什么来防止这种情况发生?

这是最初的问题,直到我根据我的发现进行更新

标题:nodejs webworker-threads调试,从哪里开始?

如果我在运行我的 nodejs 应用程序 7-8 小时后得到这种堆栈跟踪,我该如何开始调试它以在我的代码中找到罪魁祸首?

node[3836]: ../src/node_platform.cc:414:std::shared_ptr<node::PerIsolatePlatformData> node::NodePlatform::ForIsolate(v8::Isolate*): Assertion `data' failed.
 1: 0x8dc510 node::Abort() [node]
 2: 0x8dc5e5  [node]
 3: 0x965687 node::NodePlatform::CallOnForegroundThread(v8::Isolate*, v8::Task*) [node]
 4: 0xeda2ab v8::internal::IncrementalMarking::Start(v8::internal::GarbageCollectionReason) [node]
 5: 0xed4b6c v8::internal::Heap::CollectGarbage(v8::internal::AllocationSpace, v8::internal::GarbageCollectionReason, v8::GCCallbackFlags) [node]
 6: 0xed7371 v8::internal::Heap::AllocateRawWithRetryOrFail(int, v8::internal::AllocationSpace, v8::internal::AllocationAlignment) [node]
 7: 0xeac650  [node]
 8: 0xeac6e7 v8::internal::Factory::NewJSObject(v8::internal::Handle<v8::internal::JSFunction>, v8::internal::PretenureFlag) [node]
 9: 0xae84ae v8::Object::New(v8::Isolate*) [node]
10: 0x7ff7eb5f0913 BSONDeserializer::DeserializeDocumentInternal(bool) [/home/ubuntu/myapp/node_modules/webworker-threads/build/Release/WebWorkerThreads.node]
11: 0x7ff7eb5f0b97 BSONDeserializer::DeserializeDocument(bool) [/home/ubuntu/myapp/node_modules/webworker-threads/build/Release/WebWorkerThreads.node]
12: 0x7ff7eb5f0f40 BSONDeserializer::DeserializeValue(BsonType, bool) [/home/ubuntu/myapp/node_modules/webworker-threads/build/Release/WebWorkerThreads.node]
13: 0x7ff7eb5f0946 BSONDeserializer::DeserializeDocumentInternal(bool) [/home/ubuntu/myapp/node_modules/webworker-threads/build/Release/WebWorkerThreads.node]
14: 0x7ff7eb5f0b97 BSONDeserializer::DeserializeDocument(bool) [/home/ubuntu/myapp/node_modules/webworker-threads/build/Release/WebWorkerThreads.node]
15: 0x7ff7eb5f3bcf  [/home/ubuntu/myapp/node_modules/webworker-threads/build/Release/WebWorkerThreads.node]
16: 0x7ff7eb5f4519  [/home/ubuntu/myapp/node_modules/webworker-threads/build/Release/WebWorkerThreads.node]
17: 0x7ff7f25536ba  [/lib/x86_64-linux-gnu/libpthread.so.0]
18: 0x7ff7f228941d clone [/lib/x86_64-linux-gnu/libc.so.6]

这是一个类似的堆栈跟踪

 1: 0x8dc510 node::Abort() [node]
 2: 0x8dc5e5  [node]
 3: 0x965687 node::NodePlatform::CallOnForegroundThread(v8::Isolate*, v8::Task*) [node]
 4: 0xeda2ab v8::internal::IncrementalMarking::Start(v8::internal::GarbageCollectionReason) [node]
 5: 0xed4b6c v8::internal::Heap::CollectGarbage(v8::internal::AllocationSpace, v8::internal::GarbageCollectionReason, v8::GCCallbackFlags) [node]
 6: 0xed7371 v8::internal::Heap::AllocateRawWithRetryOrFail(int, v8::internal::AllocationSpace, v8::internal::AllocationAlignment) [node]
 7: 0xe9f655  [node]
 8: 0xea6eca v8::internal::Factory::NewRawOneByteString(int, v8::internal::PretenureFlag) [node]
 9: 0xea71db v8::internal::Factory::NewStringFromOneByte(v8::internal::Vector<unsigned char const>, v8::internal::PretenureFlag) [node]
10: 0xea7c2d v8::internal::Factory::NewStringFromUtf8(v8::internal::Vector<char const>, v8::internal::PretenureFlag) [node]
11: 0xae7ba9 v8::String::NewFromUtf8(v8::Isolate*, char const*, v8::NewStringType, int) [node]
12: 0x7fa4984eda83 Nan::imp::Factory<v8::String>::return_t Nan::New<v8::String, char*>(char*) [/home/ubuntu/myapp/node_modules/webworker-threads/build/Release/WebWorkerThreads.node]
13: 0x7fa4984e82ab BSON::BSON() [/home/ubuntu/myapp/node_modules/webworker-threads/build/Release/WebWorkerThreads.node]
14: 0x7fa4984e9b9e  [/home/ubuntu/myapp/node_modules/webworker-threads/build/Release/WebWorkerThreads.node]
15: 0x7fa4984ea519  [/home/ubuntu/myapp/node_modules/webworker-threads/build/Release/WebWorkerThreads.node]
16: 0x7fa49c2cd6ba  [/lib/x86_64-linux-gnu/libpthread.so.0]
17: 0x7fa49c00341d clone [/lib/x86_64-linux-gnu/libc.so.6]

每秒向网络工作者和代码至少发布 4 次消息

webworker 就是这样设置的

const Worker = require('webworker-threads').Worker;
mywebworker = new Worker('./myappwebworker.js');

setInterval(function() {  
    mywebworker.postMessage('hello');
  }, 250);

其他事件也会向工作人员触发消息。系统为 Ubuntu 16.04 和节点 V10.15.3

在节点中找到导致此问题的最佳方法是什么?

标签: node.jsweb-worker

解决方案


我想到了两件事。

  1. 如果您让调试窗口保持打开状态,则取决于应用程序,垃圾收集可能会停止,从而导致此类问题。多次通过 OpenCV 的视频等艰苦的工作流程让我失望了。
  2. setInterval()我相信,不会关心内部代码是被执行还是阻塞(也就是说,在不应该阻塞的时候阻塞或者阻塞太久)。如果阻塞超过 250 毫秒,您将建立堆栈。

也许这种代码会给你更好的调试体验,如果 postMessage 停止,你不会建立堆栈:

function doIt() {
  mywebworker.postMessage('hello');
  setTimeout(function() {
     doIt();
  },250);
}
doIt();

推荐阅读