Skip to content
This repository was archived by the owner on Aug 7, 2021. It is now read-only.

env.uglify causes FATAL ERROR: CALL_AND_RETRY_LAST Allocation failed - JavaScript heap out of memory #458

Closed
noumaans opened this issue Mar 7, 2018 · 3 comments

Comments

@noumaans
Copy link

noumaans commented Mar 7, 2018

tns run and tns build work fine for both iOS and Android, with --bundle flag and --env.aot flag.

However, uglify fails with Out of Memory for both Android and iOS, all these commands fail during webpack build stage:

tns run ios --bundle --env.aot --env.uglify
tns run android --bundle --env.aot --env.uglify
tns build ios --bundle --env.aot --env.uglify
tns build android --bundle --env.aot --env.uglify

tns info:

nativescript      4.0.0-2018-02-21-10607
tns-core-modules  3.4.1
tns-android       3.4.2 
tns-ios           3.4.1  

grep webpack package.json:

    "@ngtools/webpack": "^1.10.1",
    "copy-webpack-plugin": "^4.5.0",
    "extract-text-webpack-plugin": "^3.0.2",
    "nativescript-dev-webpack": "^0.9.2",
    "uglifyjs-webpack-plugin": "^1.2.2",
    "webpack": "^3.11.0",
    "webpack-bundle-analyzer": "^2.11.1",
    "webpack-sources": "^1.1.0"

From webpack.config.js:

    if (uglify) {
        config.plugins.push(new webpack.LoaderOptionsPlugin({ minimize: true }));

        // Work around an Android issue by setting compress = false
        const compress = platform !== "android";
        config.plugins.push(new UglifyJsPlugin({
            uglifyOptions: {
                mangle: { reserved: nsWebpack.uglifyMangleExcludes },
                compress,
            }
        }));
    }

Stacktrace:

Running webpack for Android...
 91% additional asset processing                                                        
<--- Last few GCs --->

[24217:0x104800a00]   174569 ms: Mark-sweep 1435.4 (1547.4) -> 1435.3 (1519.9) MB, 1971.5 / 0.0 ms  (+ 0.0 ms in 0 steps since start of marking, biggest step 0.0 ms, walltime since start of marking 1972 ms) last resort GC in old space requested
[24217:0x104800a00]   176595 ms: Mark-sweep 1435.3 (1519.9) -> 1435.3 (1519.9) MB, 2025.6 / 0.0 ms  last resort GC in old space requested


<--- JS stacktrace --->

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

Security context: 0x328631525ee1 <JSObject>
    2: add_parameter [0x328680d02311 <undefined>:2932] [bytecode=0x3286eb265531 offset=69](this=0x32867af68251 <Object map = 0x32866f49c459>,token=0x32867af68489 <AST_Token map = 0x32866f4abd91>)
    4: binding_element(aka binding_element) [0x328680d02311 <undefined>:3204] [bytecode=0x3286eb263a51 offset=2026](this=0x328680d02311 <undefined>,used_parameters=0x32867af68251 <Object map = 0x32866f4...

FATAL ERROR: CALL_AND_RETRY_LAST Allocation failed - JavaScript heap out of memory
 1: node::Abort() [/usr/local/opt/node@8/bin/node]
 2: node::FatalException(v8::Isolate*, v8::Local<v8::Value>, v8::Local<v8::Message>) [/usr/local/opt/node@8/bin/node]
 3: v8::Utils::ReportOOMFailure(char const*, bool) [/usr/local/opt/node@8/bin/node]
 4: v8::internal::V8::FatalProcessOutOfMemory(char const*, bool) [/usr/local/opt/node@8/bin/node]
 5: v8::internal::Factory::NewTransitionArray(int) [/usr/local/opt/node@8/bin/node]
 6: v8::internal::TransitionArray::Insert(v8::internal::Handle<v8::internal::Map>, v8::internal::Handle<v8::internal::Name>, v8::internal::Handle<v8::internal::Map>, v8::internal::SimpleTransitionFlag) [/usr/local/opt/node@8/bin/node]
 7: v8::internal::Map::CopyReplaceDescriptors(v8::internal::Handle<v8::internal::Map>, v8::internal::Handle<v8::internal::DescriptorArray>, v8::internal::Handle<v8::internal::LayoutDescriptor>, v8::internal::TransitionFlag, v8::internal::MaybeHandle<v8::internal::Name>, char const*, v8::internal::SimpleTransitionFlag) [/usr/local/opt/node@8/bin/node]
 8: v8::internal::Map::CopyAddDescriptor(v8::internal::Handle<v8::internal::Map>, v8::internal::Descriptor*, v8::internal::TransitionFlag) [/usr/local/opt/node@8/bin/node]
 9: 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) [/usr/local/opt/node@8/bin/node]
10: 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) [/usr/local/opt/node@8/bin/node]
11: v8::internal::LookupIterator::PrepareTransitionToDataProperty(v8::internal::Handle<v8::internal::JSObject>, v8::internal::Handle<v8::internal::Object>, v8::internal::PropertyAttributes, v8::internal::Object::StoreFromKeyed) [/usr/local/opt/node@8/bin/node]
12: v8::internal::Object::AddDataProperty(v8::internal::LookupIterator*, v8::internal::Handle<v8::internal::Object>, v8::internal::PropertyAttributes, v8::internal::Object::ShouldThrow, v8::internal::Object::StoreFromKeyed) [/usr/local/opt/node@8/bin/node]
13: 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) [/usr/local/opt/node@8/bin/node]
14: v8::internal::Runtime_SetProperty(int, v8::internal::Object**, v8::internal::Isolate*) [/usr/local/opt/node@8/bin/node]
15: 0x1f38f8f8463d
16: 0x1f38f906df26
@noumaans
Copy link
Author

Solved by increasing heap size.

Might be worth mentioning in README.md or
https://docs.nativescript.org/angular/best-practices/bundling-with-webpack#debugging-common-errors
that user probably needs to set NODE_OPTIONS before calling tns build.

To allocate 4GB memory (or perhaps larger depending on app complexity):
export NODE_OPTIONS=--max-old-space-size=4096

@noumaans
Copy link
Author

@sis0k0

FWIW, I'm not seeing a significant size difference with uglify:
And I've got compress set to true for Android builds as well. It would be great if you could add a link to the issue which causes Android builds to fail with compress.

Android
AOT: bundle 4.53MB, vendor 3.23MB
AOT+Uglify: bundle 4.53MB, vendor 3.22MB

iOS
AOT: bundle 4.5MB, vendor 3.33MB
AOT+Uglify: bundle 4.5MB, vendor 3.32MB

Snippet from my webpack.config.js:

    if (uglify) {
        config.plugins.push(new webpack.LoaderOptionsPlugin({ minimize: true }));

        config.plugins.push(new UglifyJsPlugin({
            uglifyOptions: {
                parallel: true,
                cache: true,
                mangle: { reserved: nsWebpack.uglifyMangleExcludes },
                compress: true
            }
        }));
    }

noumaans added a commit to noumaans/docs that referenced this issue Mar 10, 2018
Added workaround to deal with heap out of memory issues, which will happen for a reasonable sized app built on {N}.
Please see NativeScript/nativescript-dev-webpack#458

**NOTE** Windows environment variable setting has not been tested by me - please confirm / verify it for Windows. macOS / Linux has been verified to work.
@noumaans
Copy link
Author

noumaans commented Apr 7, 2018

@NickIliev would be helpful to add a comment in webpack template which alerts the user the issue will only happen with --release flag.
I unfortunately got hit with this issue after uploading APK to Google Play store (everything looked great in local checks with production flags).

e.g.:

// Work around an Android issue by setting compress = false, issue seen only when built with --release flag

My updated snippet from webpack.config.js:

    if (uglify) {
        config.plugins.push(new webpack.LoaderOptionsPlugin({ minimize: true }));

        // Work around an Android issue by setting compress = false, issue seen only when built with --release flag
        const compress = platform !== "android";
        config.plugins.push(new UglifyJsPlugin({
            uglifyOptions: {
                parallel: true,
                cache: true,
                mangle: { reserved: nsWebpack.uglifyMangleExcludes },
                compress: compress
            }
        }));
    }

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants