Fixing JavaScript heap out of memory with WebdriverIO
Throughout working on a course you usually run into bugs and issues that throw you for a loop for awhile.
In this case, it was doubly frustrating because I had previously set up webdriverio to run in my continuous integration environment (GitHub Actions) and it was working fine. Until it stopped working.
I kept getting this error:
<--- Last few GCs --->
[168:0x5ba0970] 105925 ms: Mark-sweep (reduce) 2046.6 (2050.9) -> 2045.7 (2050.9) MB, 588.4 / 0.0 ms (average mu = 0.053, current mu = 0.021) allocation failure scavenge might not succeed
[0-0]
<--- JS stacktrace --->
[0-0] FATAL ERROR: Ineffective mark-compacts near heap limit Allocation failed - JavaScript heap out of memory
[0-0] 1: 0xa3ac30 node::Abort() [/usr/local/bin/node]
[0-0] 2: 0x98a45d node::FatalError(char const*, char const*) [/usr/local/bin/node]
[0-0] 3: 0xbae25e v8::Utils::ReportOOMFailure(v8::internal::Isolate*, char const*, bool) [/usr/local/bin/node]
[0-0] 4: 0xbae5d7 v8::internal::V8::FatalProcessOutOfMemory(v8::internal::Isolate*, char const*, bool) [/usr/local/bin/node]
[0-0] 5: 0xd56125 [/usr/local/bin/node]
[0-0] 6: 0xd56acb v8::internal::Heap::RecomputeLimits(v8::internal::GarbageCollector) [/usr/local/bin/node]
[0-0] 7: 0xd6481c v8::internal::Heap::PerformGarbageCollection(v8::internal::GarbageCollector, v8::GCCallbackFlags) [/usr/local/bin/node]
[0-0] 8: 0xd65684 v8::internal::Heap::CollectGarbage(v8::internal::AllocationSpace, v8::internal::GarbageCollectionReason, v8::GCCallbackFlags) [/usr/local/bin/node]
[0-0] 9: 0xd680fc v8::internal::Heap::AllocateRawWithRetryOrFailSlowPath(int, v8::internal::AllocationType, v8::internal::AllocationOrigin, v8::internal::AllocationAlignment) [/usr/local/bin/node]
[0-0] 10: 0xd2f3aa v8::internal::Factory::AllocateRaw(int, v8::internal::AllocationType, v8::internal::AllocationAlignment) [/usr/local/bin/node]
[0-0] 11: 0xd29254 v8::internal::FactoryBase<v8::internal::Factory>::AllocateRawWithImmortalMap(int, v8::internal::AllocationType, v8::internal::Map, v8::internal::AllocationAlignment) [/usr/local/bin/node]
[0-0] 12: 0xd2a789 v8::internal::FactoryBase<v8::internal::Factory>::NewStruct(v8::internal::InstanceType, v8::internal::AllocationType) [/usr/local/bin/node]
[0-0] 13: 0xd36be6 v8::internal::Factory::NewStackTraceFrame(v8::internal::Handle<v8::internal::FrameArray>, int) [/usr/local/bin/node]
[0-0] 14: 0xc28a98 [/usr/local/bin/node]
[0-0] 15: 0xc2fb66 v8::internal::Builtin_CallSitePrototypeToString(int, unsigned long*, v8::internal::Isolate*) [/usr/local/bin/node]
[0-0] 16: 0x13f5159 [/usr/local/bin/node]
What was weird is that the tests all passed!
It did not turn out to be a Selenium Grid issue, as I wasn't using that but it turned out to be another simple fix (i.e. nothing to do with memory size).
I was missing the @wdio/sync
package from my package dependencies after I split out my e2e tests into a separate folder.
Once I added @wdio/sync
back, things worked.
"dependencies": {
"@wdio/cli": "6.1.24",
"@wdio/local-runner": "6.1.24",
"@wdio/mocha-framework": "6.1.19",
"@wdio/spec-reporter": "6.1.23",
+ "@wdio/sync": "6.1.14"
}
The telltale sign was that the tests were taking 1 minute when before I checked the logs and the tests used to run in 4 seconds. Ding, ding, ding! It must not wait properly for the commands without the sync package and uses up more and more memory.
Hope this helps anyone in a similar situation!