在Google云服务的f1微实例中,node.js进程的进程内存限制?

时间:2018-04-02 01:11:09

标签: node.js google-cloud-platform google-compute-engine v8

我试图在Google云服务上获得一个非常基本的基于node.js的项目/网站,并且正在玩他们的免费f1微服务器之一。据推测,这些可提供约600mb的柱塞。 htop为我确认了这一点,并告诉我,在空闲时,它占用了大约112mb(默认为0K交换,fwiw)。

我尝试起床的项目的一个特点是,为了最大程度的简化和速度,我require()一个~75mb的json对象进入我的节点进程的内存,而不是数据库。 / p>

在当地,这没问题。但是当我尝试在f1微实例上运行应用程序时,我得到以下错误输出:

ft@instance-1:~/code/zipcode-mapping$ node app.js --max-old-space-size
`<--- Last few GCs --->`
re[2678:0x24bc6b0]      759 ms: Mark-sweep 163.7 (180.4) -> 137.6 (180.4) MB, 19.7 / 0.0 ms  (+ 75.4 ms in 248 steps since start of marking, biggest step 0.8 ms, walltime since start of marking 160 ms) finalize incremental marking via stack guard GC in old [2678:0x24bc6b0]     1483 ms: Mark-sweep 267.9 (307.6) -> 226.3 (306.1) MB, 13.3 / 0.0 ms  (+ 172.3 ms in 260 steps since start of marking, biggest step 5.1 ms, walltime since start of marking 257 ms) finalize incremental marking via stack guard GC in old
<--- JS stacktrace --->
Cannot get stack trace in GC.
FATAL ERROR: NewSpace::Rebalance Allocation failed - process out of memory
 1: node::Abort() [node]
 2: 0x11e7fec [node]
 3: v8::Utils::ReportOOMFailure(char const*, bool) [node]
 4: v8::internal::V8::FatalProcessOutOfMemory(char const*, bool) [node]
 5: 0xad2f0b [node]
 6: v8::internal::MarkCompactCollector::Evacuate() [node]
 7: v8::internal::MarkCompactCollector::CollectGarbage() [node]
 8: v8::internal::Heap::MarkCompact() [node]
 9: v8::internal::Heap::PerformGarbageCollection(v8::internal::GarbageCollector, v8::GCCallbackFlags) [node]
10: v8::internal::Heap::CollectGarbage(v8::internal::AllocationSpace, v8::internal::GarbageCollectionReason, v8::GCCallbackFlags) [node]
11: v8::internal::Factory::NewFixedDoubleArray(int, v8::internal::PretenureFlag) [node]
12: v8::internal::JsonParser<true>::ParseJsonArray() [node]
13: v8::internal::JsonParser<true>::ParseJsonValue() [node]
14: v8::internal::JsonParser<true>::ParseJsonArray() [node]
15: v8::internal::JsonParser<true>::ParseJsonValue() [node]
16: v8::internal::JsonParser<true>::ParseJsonArray() [node]
17: v8::internal::JsonParser<true>::ParseJsonValue() [node]
18: v8::internal::JsonParser<true>::ParseJsonObject() [node]
19: v8::internal::JsonParser<true>::ParseJsonValue() [node]
20: v8::internal::JsonParser<true>::ParseJsonObject() [node]
21: v8::internal::JsonParser<true>::ParseJsonValue() [node]
22: v8::internal::JsonParser<true>::ParseJsonArray() [node]
23: v8::internal::JsonParser<true>::ParseJsonValue() [node]
24: v8::internal::JsonParser<true>::ParseJsonObject() [node]
25: v8::internal::JsonParser<true>::ParseJsonValue() [node]
26: v8::internal::JsonParser<true>::ParseElement(v8::internal::Handle<v8::internal::JSObject>) [node]
27: v8::internal::JsonParser<true>::ParseJsonObject() [node]
28: v8::internal::JsonParser<true>::ParseJsonValue() [node]
29: v8::internal::JsonParser<true>::ParseJson() [node]
30: v8::internal::Builtin_JsonParse(int, v8::internal::Object**, v8::internal::Isolate*) [node]
31: 0x17b0a8697d
Aborted

我的问题是,如何确定过程内存限制(以及该限制的来源),如果合理,我该如何扩展它们?

干杯。

3 个答案:

答案 0 :(得分:1)

V8开发者在这里。 TL; DR:看起来你根本没有足够的可用内存来做你想做的事。

在最后两次成功运行GC之后,JavaScript堆的预留内存分别为180MB和306MB。下一次GC尝试失败,因为操作系统拒绝向该进程提供另一个页面。可以肯定的是,当时堆内存消耗大约为450MB,这大约是您的设置所允许的。

“75MB JSON对象”是什么意思?如果JSON字符串的大小为75MB,则解析后的对象将比这大得多。使用不需要将所有数据保存在内存中的数据库可能是有意义的。

此外,仅--max-old-space-size什么都不做;该标志的目的是指定一个值,例如--max-old-space-size=1000最大堆大小为1000MB。但是,这不是你的问题,因为你没有遇到堆限制,这是有道理的,因为默认值比服务器提供的更多。

答案 1 :(得分:1)

您可以尝试创建交换文件(请参见下文)。它将具有创建更多内存的效果,但显然内存访问速度非常慢。

if [ ! -f /swapfile1 ]; then
    #the name of the user that runs the app
    USER=myapp 
    #size of the swap file (1Gb)
    SIZE=1048576

    dd if=/dev/zero of=/swapfile1 bs=1024 count=$SIZE
    chown $USER:$USER /swapfile1
    chmod 0600 /swapfile1
    mkswap /swapfile1
    swapon /swapfile1
    echo /swapfile1 none swap sw 0 0 >> /etc/fstab
fi

然后检查它是否与free -m一起使用。在f1微型计算机上,应该是这样的:

$ free -m
              total        used        free      shared  buff/cache   available
Mem:            592         210         104           1         277         268
Swap:          1023         112         911

答案 2 :(得分:0)

您可以在bashsh中查看其内置的ulimit命令,特别是:

$ ulimit -v

进程可用的最大虚拟内存量。

有一篇有趣的文章here,另请注意命令$ ulimit -a,它允许您检查有关项目的所有限制。

请注意,如果标签为“unlimited”,则表示受到实际机器限制的限制,一旦机器资源不足(如果它被选中),它将被OOM杀死。