Will Luce
Will Luce

Reputation: 1841

JS heap out of memory for Angular testing

I have a memory issue I'm trying to figure out and I don't really know where to start. When I'm running tests, I get a JS heap issue and my tests will error out without ever running. My hunch is that it is being caused by a very large strings file that I use for internationalization. This is an inherited project so I'll outline what currently happens and maybe someone can help me figure out a way to make it better.

In the main application

A file inject.en.js is a 2.2MB json file containing translated strings for the application.

var INJECT_en = { ... };

To have it available as early as possible, it is included as a global var in the applications index.html

<script src="js/languages/hybrid.inject.en.js" type="text/javascript"></script>

It is then used to build up a global config object.

var windowJS =  new WindowService().nativeWindow;
var HybridInject = windowJS.HybridInject_en; // custom app strings
var INJECT = windowJS.INJECT_en;
var startInjector = _.merge(_.clone(HybridInject), _.clone(INJECT));

export const CONFIG: ConfigType = {
    ...
    strings: populateStrings(startInjector),
    ...

}

For testing

I'm using Jest for testing this application for a number of reasons. I tried a few things to set Jest up to have those files available in the same way when the CONFIG is build and I settled on the following for my jestGlobalMocks.ts.

I copied the files into a testing directory and converted them to export the object.

export const INJECT_en = { ... }

Then made them available to the CONFIG build by making them available on the window.

Object.defineProperty(window, 'HybridInject_en', {value: HybridInject_en});
Object.defineProperty(window, 'INJECT_en', {value: INJECT_en});

The result

When tests are run, I get the following output

[BABEL] Note: The code generator has deoptimised the styling of "jest/configs/inject.en.ts" as it exceeds the max of "500KB".



<--- Last few GCs --->



[208:0x37d62f0]    86678 ms: Scavenge 1384.7 (1422.5) -> 1383.8 (1423.0) MB, 11.5 / 0.1 ms  (average mu = 0.143, current mu = 0.101) allocation failure 

[208:0x37d62f0]    86694 ms: Scavenge 1384.7 (1423.0) -> 1383.9 (1423.5) MB, 13.5 / 0.1 ms  (average mu = 0.143, current mu = 0.101) allocation failure 

[208:0x37d62f0]    86710 ms: Scavenge 1384.9 (1423.5) -> 1384.2 (1424.0) MB, 13.5 / 0.1 ms  (average mu = 0.143, current mu = 0.101) allocation failure 





<--- JS stacktrace --->



==== JS stack trace =========================================



    0: ExitFrame [pc: 0x255fdc5dbe1d]

Security context: 0x0e1a9b79e6e1 <JSObject>

    1: SourceMapConsumer_allGeneratedPositionsFor [0x32dd014cb6a1] [/var/jenkins_home/workspace/base_jenkins-build/node_modules/source-map/lib/source-map-consumer.js:~178] [pc=0x255fdcb3491a](this=0x0319d2aa8031 <BasicSourceMapConsumer map = 0x68f75371d81>,aArgs=0x1954c0c022a9 <Object map = 0x68f75372671>)

    2: /* anonymous */(aka /* anonymous */...



FATAL ERROR: Ineffective mark-compacts near heap limit Allocation failed - JavaScript heap out of memory

 1: 0x8daaa0 node::Abort() [node]

 2: 0x8daaec  [node]

 3: 0xad73ce v8::Utils::ReportOOMFailure(v8::internal::Isolate*, char const*, bool) [node]

 4: 0xad7604 v8::internal::V8::FatalProcessOutOfMemory(v8::internal::Isolate*, char const*, bool) [node]

 5: 0xec4c32  [node]

 6: 0xec4d38 v8::internal::Heap::CheckIneffectiveMarkCompact(unsigned long, double) [node]

 7: 0xed0e12 v8::internal::Heap::PerformGarbageCollection(v8::internal::GarbageCollector, v8::GCCallbackFlags) [node]

 8: 0xed1744 v8::internal::Heap::CollectGarbage(v8::internal::AllocationSpace, v8::internal::GarbageCollectionReason, v8::GCCallbackFlags) [node]

 9: 0xed43b1 v8::internal::Heap::AllocateRawWithRetryOrFail(int, v8::internal::AllocationSpace, v8::internal::AllocationAlignment) [node]

10: 0xe9d834 v8::internal::Factory::NewFillerObject(int, bool, v8::internal::AllocationSpace) [node]

11: 0x113cf9e v8::internal::Runtime_AllocateInNewSpace(int, v8::internal::Object**, v8::internal::Isolate*) [node]

12: 0x255fdc5dbe1d 

Aborted

npm ERR! Test failed.  See above for more details.

Upvotes: 0

Views: 3405

Answers (2)

Mr. Droid
Mr. Droid

Reputation: 340

I after struggling for a while i managed to fixed this issue by replacing all ^ by ~ from the all the dependencies in package.json file.

Replace

  "dependencies": {
     "@agm/core": "^1.0.0-beta.5",
    "@angular/animations": "^7.2.0",
    "@angular/common": "^7.2.0",
    "@angular/compiler": "^7.2.0",
    "@angular/core": "^7.2.0",
    "@angular/forms": "^7.2.0",
    ...

  },

To

  "dependencies": {
     "@agm/core": "~1.0.0-beta.5",
    "@angular/animations": "~7.2.0",
    "@angular/common": "~7.2.0",
    "@angular/compiler": "~7.2.0",
    "@angular/core": "~7.2.0",
    "@angular/forms": "~7.2.0",
    ...

  },

I think this issue is because of conflict between different version of libraries.

Upvotes: 0

JimB
JimB

Reputation: 1163

In your script section of your package.json you should increase the heap (example below but you'll need to adapt for your uses, i've never used jest)

"gulp": "node --max_old_space_size=2560 ./node_modules/gulp/bin/gulp",
"run-build": "npm run gulp",
"run-build-with-switches": "npm run gulp -- myspecialtarget"

The first line sets up a script that runs gulp with increased heap anytime you reference it with npm run gulp. The second line will run the first script with no arguments (for gulp this means default target). The third line will run gulp with the argument myspecialtarget.

Upvotes: 1

Related Questions