【发布时间】:2019-01-09 07:19:00
【问题描述】:
我正在使用 Express 4 + Sequelize + Postgresql 数据库构建 NodeJs 应用程序。 我正在使用 Node v8.11.3。
我编写了一个脚本来将数据从 JSON 文件加载到我的数据库中。我用大约 30 个实体样本测试了脚本。效果很好。
实际上,在完整的 JSON 文件中,我有大约 100 000 个实体要加载。我的脚本读取 JSON 文件并尝试异步填充数据库(即同时填充 100 000 个实体)。
几分钟后结果是:
<--- Last few GCs --->
[10488:0000018619050A20] 134711 ms: Mark-sweep 1391.6 (1599.7) -> 1391.6 (1599.7) MB, 1082.3 / 0.0 ms allocation failure GC in old space requested
[10488:0000018619050A20] 136039 ms: Mark-sweep 1391.6 (1599.7) -> 1391.5 (1543.7) MB, 1326.9 / 0.0 ms last resort GC in old space requested
[10488:0000018619050A20] 137351 ms: Mark-sweep 1391.5 (1543.7) -> 1391.5 (1520.2) MB, 1311.5 / 0.0 ms last resort GC in old space requested
<--- JS stacktrace --->
==== JS stack trace =========================================
Security context: 0000034170025879 <JSObject>
1: split(this=00000165BEC5DB99 <Very long string[1636]>)
2: attachExtraTrace [D:\Code\backend-lymo\node_modules\bluebird\js\release\debuggability.js:~775] [pc=0000021115C5728E](this=0000003CA90FF711 <CapturedTrace map = 0000033AD0FE9FB1>,error=000001D3EC5EFD59 <Error map = 00000275F61BA071>)
3: _attachExtraTrace(aka longStackTracesAttachExtraTrace) [D:\Code\backend-lymo\node_module...
FATAL ERROR: CALL_AND_RETRY_LAST Allocation failed - JavaScript heap out of memory
1: node_module_register
2: v8::internal::FatalProcessOutOfMemory
3: v8::internal::FatalProcessOutOfMemory
4: v8::internal::Factory::NewFixedArray
5: v8::internal::HashTable<v8::internal::SeededNumberDictionary,v8::internal::SeededNumberDictionaryShape>::IsKey
6: v8::internal::HashTable<v8::internal::SeededNumberDictionary,v8::internal::SeededNumberDictionaryShape>::IsKey
7: v8::internal::StringTable::LookupString
8: v8::internal::StringTable::LookupString
9: v8::internal::RegExpImpl::Exec
10: v8::internal::interpreter::BytecodeArrayRandomIterator::UpdateOffsetFromIndex
11: 0000021115A043C1
最后,已经创建了一些实体,但该过程显然崩溃了。 我知道这个错误是由于记忆造成的。
我的问题是:为什么 Node 不花时间管理所有事情而不超出内存?有没有“队列”来限制这种爆炸?
我发现了一些解决方法:
- 将种子分割成几个 JSON 文件
- 使用 --max_old_space_size=8192 选项使用更多内存
- 按顺序进行(使用同步调用)
但是这些解决方案都没有让我满意。这让我担心我的应用程序的未来应该在生产中管理有时很长的操作。
你怎么看?
【问题讨论】:
-
如果您需要帮助,您可能需要向我们展示您的代码。如果您在一个循环中一次启动 100,000 个数据库操作,那就太多了。如果您向我们展示您的特定代码,我们只能为您提供具体建议。
-
Node 做你告诉它的事情。如果你指示它做一些占用大量内存的事情,这就是它试图做的事情。很有可能是您的代码需要修复。欢迎来到编程和编写优秀代码的需求。
-
@jfriend00 感谢您的回答。实际上我不想让你调试我的代码,这就是我没有发布它的原因。我的意思是了解 NodeJs 如何处理大量异步计算/IO。你回答了我的问题:“Node 做你告诉它的事情。如果你指示它做一些需要大量内存的事情,那它就是它试图做的事情。”所以我知道我必须将异步调用限制在一个限度内。
标签: node.js