Nuxt.jsでまさかのメモリエラーが出た際の記録です。先に結論を書くと、middlewareでstoreを参照した際なのかlayoutでstoreを参照したタイミングでエラーになり無限redirect loopしていたのが根本原因でした。しかもSafariだけ!!なぜかchromeは問題ないという・・・
エラーログ
<--- Last few GCs --->
[65052:0x102b00000] 272190 ms: Mark-sweep 1286.5 (1454.8) -> 1272.4 (1455.3) MB, 1763.0 / 0.1 ms (average mu = 0.292, current mu = 0.241) allocation failure scavenge might not succeed
[65052:0x102b00000] 274089 ms: Mark-sweep 1281.4 (1455.8) -> 1273.1 (1455.8) MB, 1712.4 / 0.1 ms (average mu = 0.201, current mu = 0.098) allocation failure GC in old space requested
<--- JS stacktrace --->
==== JS stack trace =========================================
0: ExitFrame [pc: 0xe8c81d5be3d]
Security context: 0x354fb4a9e6e9 <JSObject>
1: mergeOptions(aka mergeOptions) [0x354fd11fe731] [/Home/node_modules/vue/dist/vue.runtime.common.dev.js:~1508] [pc=0xe8c8281d46d](this=0x354f210826f1 <undefined>,parent=0x354fd4199bb9 <Object map = 0x354f8b906df9>,child=0x354f4ceb3089 <Object map = 0x354fa0a03fe9>,vm=0x354f4ceb8b99 <Vue map = 0x354f77da7f59>)
2: _i...
FATAL ERROR: Ineffective mark-compacts near heap limit Allocation failed - JavaScript heap out of memory
1: 0x10003cf99 node::Abort() [/Home/.nodebrew/current/bin/node]
2: 0x10003d1a3 node::OnFatalError(char const*, char const*) [/Home/.nodebrew/current/bin/node]
3: 0x1001b7835 v8::internal::V8::FatalProcessOutOfMemory(v8::internal::Isolate*, char const*, bool) [/Home/.nodebrew/current/bin/node]
4: 0x100585682 v8::internal::Heap::FatalProcessOutOfMemory(char const*) [/Home/.nodebrew/current/bin/node]
5: 0x100588155 v8::internal::Heap::CheckIneffectiveMarkCompact(unsigned long, double) [/Home/.nodebrew/current/bin/node]
6: 0x100583fff v8::internal::Heap::PerformGarbageCollection(v8::internal::GarbageCollector, v8::GCCallbackFlags) [/Home/.nodebrew/current/bin/node]
7: 0x1005821d4 v8::internal::Heap::CollectGarbage(v8::internal::AllocationSpace, v8::internal::GarbageCollectionReason, v8::GCCallbackFlags) [/Home/.nodebrew/current/bin/node]
8: 0x10058ea6c v8::internal::Heap::AllocateRawWithLigthRetry(int, v8::internal::AllocationSpace, v8::internal::AllocationAlignment) [/Home/.nodebrew/current/bin/node]
9: 0x10058eaef v8::internal::Heap::AllocateRawWithRetryOrFail(int, v8::internal::AllocationSpace, v8::internal::AllocationAlignment) [/Home/.nodebrew/current/bin/node]
10: 0x1005664f2 v8::internal::Factory::NewMap(v8::internal::InstanceType, int, v8::internal::ElementsKind, int) [/Home/.nodebrew/current/bin/node]
11: 0x1006aa0eb v8::internal::Map::RawCopy(v8::internal::Handle<v8::internal::Map>, int, int) [/Home/.nodebrew/current/bin/node]
12: 0x1006a36aa v8::internal::Map::CopyDropDescriptors(v8::internal::Handle<v8::internal::Map>) [/Home/.nodebrew/current/bin/node]
13: 0x1006aa5af v8::internal::Map::ShareDescriptor(v8::internal::Handle<v8::internal::Map>, v8::internal::Handle<v8::internal::DescriptorArray>, v8::internal::Descriptor*) [/Home/.nodebrew/current/bin/node]
14: 0x100696014 v8::internal::Map::CopyAddDescriptor(v8::internal::Handle<v8::internal::Map>, v8::internal::Descriptor*, v8::internal::TransitionFlag) [/Home/.nodebrew/current/bin/node]
15: 0x100695e32 v8::internal::Map::CopyWithField(v8::internal::Handle<v8::internal::Map>, v8::internal::Handle<v8::internal::Name>, v8::internal::Handle<v8::internal::FieldType>, v8::internal::PropertyAttributes, v8::internal::PropertyConstness, v8::internal::Representation, v8::internal::TransitionFlag) [/Home/.nodebrew/current/bin/node]
16: 0x1006ac682 v8::internal::Map::TransitionToDataProperty(v8::internal::Handle<v8::internal::Map>, v8::internal::Handle<v8::internal::Name>, v8::internal::Handle<v8::internal::Object>, v8::internal::PropertyAttributes, v8::internal::PropertyConstness, v8::internal::Object::StoreFromKeyed) [/Home/.nodebrew/current/bin/node]
17: 0x100677288 v8::internal::LookupIterator::PrepareTransitionToDataProperty(v8::internal::Handle<v8::internal::JSReceiver>, v8::internal::Handle<v8::internal::Object>, v8::internal::PropertyAttributes, v8::internal::Object::StoreFromKeyed) [/Home/.nodebrew/current/bin/node]
18: 0x10069cae4 v8::internal::Object::AddDataProperty(v8::internal::LookupIterator*, v8::internal::Handle<v8::internal::Object>, v8::internal::PropertyAttributes, v8::internal::ShouldThrow, v8::internal::Object::StoreFromKeyed) [/Home/.nodebrew/current/bin/node]
19: 0x100804019 v8::internal::Runtime::SetObjectProperty(v8::internal::Isolate*, v8::internal::Handle<v8::internal::Object>, v8::internal::Handle<v8::internal::Object>, v8::internal::Handle<v8::internal::Object>, v8::internal::LanguageMode) [/Home/.nodebrew/current/bin/node]
20: 0x100807863 v8::internal::Runtime_SetProperty(int, v8::internal::Object**, v8::internal::Isolate*) [/Home/.nodebrew/current/bin/node]
21: 0xe8c81d5be3d
Abort trap: 6
対処法
package.jsonに「–max_old_space_size=2048 –optimize_for_size」を追加。
{
"scripts": {
"dev": "nuxt --max_old_space_size=2048 --optimize_for_size",
},
ひとまずメモリエラーで落ちることはなくなったものの、Safariでリダイレクトループする問題が発生。
リダイレクトループの原因
middlewareとlayoutのmountedでstoreを参照する際に、ちゃんとundefineチェックするように修正したらなおりました。
middleware
export default function ({ app, store, params, route, redirect, req, $axios }) {
if (!process.server) return;
// ↓これを追加
if (store.state.user && store.state.user != null) {
// 処理
layoutのmounted。格好わるいけどdataでちゃんと定義してundefineチェックを追加
export default {
data: (context) => ({
user: {
hogehoge: {}
}
}),
mounted() {
if (this.$store.state.user) {
this.user = this.$store.state.user;
}
}
}
ちょっとした変更である日突然発生するうえ原因がわかりづらいから気をつけないとですね & テストコードあるといいのかも