nodejs_bug修复
发布时间:2025-05-23 05:11:08 发布人:远客网络
一、nodejs_bug修复
1、Ineffective mark-compacts near heap limit Allocation failed- JavaScript heap out of memory
[3628:0000020F92556310] 101267813 ms: Mark-sweep 2045.8(2063.6)-> 2045.7(2061.1) MB, 823.6/ 0.0 ms(+ 217.9 ms in 2 steps since start of marking, biggest step 217.9 ms, walltime since start of marking 1052 ms)(average mu= 0.052, current mu= 0.011)
==== JS stack trace=========================================
Security context: 0x016990671ba1<JSObject>
1: parseMessage [00000302F1DB3371] [C:\Platform\node\service\node_modules\pg\lib\connection.js:~377] [pc=0000028DA566DDB0](this=0x03d27f47c261<Connection map= 0000012A6A060F51>,0x03e134ba35c9<Uint8Array map=
2:/* anonymous*/ [0000020ACD5EAF31] [C:\Platform\node\service\node_modules\pg\lib\connection.js:~119] [pc=0000028DA56...
FATAL ERROR: Ineffective mark-compacts near heap limit Allocation failed- JavaScript heap out of memory
1: 00007FF78BAC094F napi_wrap+124431
2: 00007FF78BA62696 v8::base::CPU::has_sse+34502
3: 00007FF78BA63356 v8::base::CPU::has_sse+37766
4: 00007FF78C266F4E v8::Isolate::ReportExternalAllocationLimitReached+94
5: 00007FF78C24EF91 v8::SharedArrayBuffer::Externalize+833
6: 00007FF78C11C85C v8::internal::Heap::EphemeronKeyWriteBarrierFromCode+1436
7: 00007FF78C127C00 v8::internal::Heap::ProtectUnprotectedMemoryChunks+1312
8: 00007FF78C124734 v8::internal::Heap::PageFlagsAreConsistent+3204
9: 00007FF78C119FC3 v8::internal::Heap::CollectGarbage+1283
10: 00007FF78C118794 v8::internal::Heap::AddRetainedMap+2356
11: 00007FF78C140623 v8::internal::Factory::NewRawOneByteString+83
12: 00007FF78C1434D2 v8::internal::Factory::NewStringFromUtf8+130
13: 00007FF78C26386A v8::String::NewFromUtf8+298
14: 00007FF78B9D76EF node::tracing::TraceEventHelper::SetAgent+40751
15: 00007FF78BA79BFD v8::internal::Malloced::operator delete+1661
16: 00007FF78C61341C v8::internal::SetupIsolateDelegate::SetupHeap+4562817: 0000028DA566DDB0
2、<--- JS stacktrace--->
Cannot get stack trace in GC.
FATAL ERROR: MarkCompactCollector: semi-space copy, fallback in old gen Allocation failed- JavaScript heap out of memory
这个问题是node内存泄漏造成的。因为node是单线程的,所有的访问走的一个线程,如果执行完一个,占用内存增加,但是没有释放的话,就造成内存泄漏,内存泄漏其实就是存储泄漏,而造成的原因就是内存分配超过了v8内存的限制数量,而且进程所占用的内存,并没有慢慢释放回来,
解决办法:node--max-old-space-size=6096 analysis.js
二、深入理解 Node.js 的 Buffer
1、深入理解 Node.js的 Buffer模块,本文旨在解析 Buffer模块的核心实现以及 V8堆外内存的管理原理。Buffer是 Node.js中极为重要且广泛使用的模块,其底层实现复杂但逻辑清晰,主要涉及 JS层和 C++层。
2、在 JS层实现中,Buffer的核心逻辑主要集中在从 `Buffer.from`方法开始的内存分配。当传入的长度大于 Node.js设置的阈值时,会通过 C++层直接分配内存。否则,若之前剩下的内存足够,则直接分配。Node.js初始化时预先分配一大块内存由 JS管理,每次从该内存中切分一部分给使用方,若不够则扩容。`createPool`方法是关键步骤,最终通过 `Uint8Array`实现内存分配,从内存池中分配一块内存。
3、在 C++层实现中,内存分配和管理的过程涉及 V8内核的多个对象间的关系。通过 `createFromString`直接从 C++层申请内存的实现,涉及从 `V8`对象链路到 `ArrayBuffer`和 `Uint8Array`的构建。`CreateTrackedArrayBuffer`方法创建了一个 `ArrayBuffer`对象,进而通过 `Uint8Array`实现内存的封装。`NewBackingStore`方法创建 `BackingStore`对象,用于管理分配的内存。在 GC(垃圾回收)时,`BackingStore`的析构函数会执行预设的回调,通知 `V8`管理堆外内存的变化。
4、此外,还有 C++层的另一种内存分配和释放方式,通过 `Buffer`提供的 `EncodeUtf8String`函数实现字符串编码时的内存管理。在这里,内存分配和释放由 `V8`负责,`AllocatedBuffer`和 `BackingStore`对象的交互展示了这一过程。
5、在 JS层的 `Uint8Array`实现中,内存主要基于 V8的堆管理,而非堆外内存。只有在使用 `buffer`属性时,才会触发堆外内存的申请以替代初始化时在 V8堆内的内存分配,并将数据复制过来。这种行为体现了内存管理的灵活性和高效性。
6、堆外内存的管理涉及到 Node.js和 V8的合作。Buffer的内存释放由 V8跟踪,与堆内内存的释放机制有所不同。在实际应用中,通过代码断点调试或观察内存变化,可以深入了解堆外内存的生命周期管理。
7、综上所述,深入理解 Buffer的实现和内存管理原理,不仅能够优化代码性能,还能在遇到内存问题时提供解决问题的线索。掌握这些底层知识,对于提升 Node.js应用的稳定性和效率具有重要意义。
三、javascript 和 protobuf
1、代码块:这段代码展示了如何使用protobufjs库来加载和解析Protocol Buffers(protobuf)定义文件。首先,使用response.text()将响应内容读取为文本,该文本包含了protobuf的定义。接着,利用protobuf.parse(content)方法解析文本内容,获取包含解析后所有定义的对象。之后,通过调用root.lookupType('protobuf.WsFrameData')在解析得到的protobuf定义中查找名为WsFrameData的消息类型。找到后,将其赋值给MessagePb变量,便于进行特定格式消息的编码或解码。
2、代码块:接收二进制数据通过event.data获取一个Blob对象,代表不可变原始数据。使用await blob.arrayBuffer()将Blob对象异步转换为ArrayBuffer。接着,通过newUint8Array(buffer)创建Uint8Array,提供对ArrayBuffer的无符号8位整数视图。最后,利用await MessagePb.decode(data)调用protobuf库的decode方法,将二进制数据解码为应用程序可操作的对象。
3、这段代码的总体作用是处理基于protobuf的二进制通信协议,将接收到的二进制数据转换为ArrayBuffer,通过Uint8Array访问并最终使用protobuf的解码方法将其解码为易于操作的对象,这是处理protobuf通信协议的常见做法。