我试图在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
我的问题是,如何确定过程内存限制(以及该限制的来源),如果合理,我该如何扩展它们?
干杯。
答案 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)