microsoft / TypeScript

TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
https://www.typescriptlang.org
Apache License 2.0
101k stars 12.48k forks source link

FATAL ERROR: CALL_AND_RETRY_LAST Allocation failed - process out of memory #14628

Closed pltnkv closed 7 years ago

pltnkv commented 7 years ago

TypeScript Version: 2.2.1

ts-loader version: 1.3.2 and 2.0.1 (probably no matter) node version: v4.7.2 and v6.9.5 (probably no matter)

I use webpack + ts-loader with next config:

ts: {
    transpileOnly: true,
    compilerOptions: {
        target: 'ES5',
        jsx: 'react',
        sourceMap: true
    }
},

After upgrade typescript from 2.0.3 to 2.2.1 compilation fail with next error:

ts-loader: Using typescript@2.2.1 and /mnt/ssd/home/oleg/IdeaProjects/hc/application/src/tsconfig.json                                                                                           49% 1306/2000 build modules
<--- Last few GCs --->

  173682 ms: Mark-sweep 1354.8 (1435.6) -> 1354.8 (1435.6) MB, 979.1 / 0.0 ms [allocation failure] [GC in old space requested].
  174623 ms: Mark-sweep 1354.8 (1435.6) -> 1354.8 (1435.6) MB, 940.7 / 0.0 ms [allocation failure] [GC in old space requested].
  175574 ms: Mark-sweep 1354.8 (1435.6) -> 1357.5 (1407.6) MB, 951.1 / 0.0 ms [last resort gc].
  176520 ms: Mark-sweep 1357.5 (1407.6) -> 1360.5 (1407.6) MB, 945.5 / 0.0 ms [last resort gc].

<--- JS stacktrace --->

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

Security context: 0x17e3fb1cfb51 <JS Object>
    1: toString [native v8natives.js:~642] [pc=0x331e2359bef6] (this=0x2fae35ff1a9 <Number: nan>,u=0x17e3fb104381 <undefined>)
    2: arguments adaptor frame: 0->1
    3: isNumericLiteralName [/mnt/ssd/home/oleg/IdeaProjects/hc/node_modules/typescript/lib/typescript.js:~35538] [pc=0x331e212c2339] (this=0x17e3fb1e6111 <JS Global Object>,name=0x1b5b1edec079 <String[8]: sendStat>)
    4: isNumeric...

FATAL ERROR: CALL_AND_RETRY_LAST Allocation failed - JavaScript heap out of memory
 1: node::Abort() [grunt]
 2: 0x1096a4c [grunt]
 3: v8::Utils::ReportApiFailure(char const*, char const*) [grunt]
 4: v8::internal::V8::FatalProcessOutOfMemory(char const*, bool) [grunt]
 5: v8::internal::Factory::NewRawOneByteString(int, v8::internal::PretenureFlag) [grunt]
 6: v8::internal::Factory::NewStringFromOneByte(v8::internal::Vector<unsigned char const>, v8::internal::PretenureFlag) [grunt]
 7: v8::internal::Factory::NumberToString(v8::internal::Handle<v8::internal::Object>, bool) [grunt]
 8: v8::internal::Runtime_NumberToStringSkipCache(int, v8::internal::Object**, v8::internal::Isolate*) [grunt]
 9: 0x331e200092a7

Expected behavior: Compilation success

Actual behavior: Compilation fail

RyanCavanaugh commented 7 years ago

We need a zip file or repo we can run, preferably without ts-loader if at all possible

pltnkv commented 7 years ago

Sorry, but i can't send you source code. Maybe you can suggest in what direction i should investigate?

RyanCavanaugh commented 7 years ago

This is something we'd have to investigate from our side. It's possible (but unlikely) there's some odd one-off pattern that's causing runaway allocation, in which case you may be able to reduce the problem to a representative repro. Otherwise we're kind of at a dead end here.

Just for our information gathering purposes, how big (MB of .ts) is your project?

pltnkv commented 7 years ago

Size: 9.5Mb Number of .ts files: 3440

It works when compile project without ts-loader, with tsc only. I try to reduce the problem. If I can not do it, I'll write it.

aight8 commented 7 years ago

See also here: #14681 Same issue here.

aight8 commented 7 years ago

any idea about this? how can I help...? can't build with webpack anything with TS currently and the error is more than mystical. it crashes always, so annoying.

kloncentaur8 commented 7 years ago

having the same problem with "typescript": "~2.3.0-dev.20170301"

mhegazy commented 7 years ago

@aight8 and @targunp can you share a repro project we can use to investigate?

myknbani commented 7 years ago

happens to me as well....i left the project untouched for a while.. it used to compile before

myknbani commented 7 years ago

I was able to fix it by having include in my tsconfig.json

Strange, I did not need to do that before

aight8 commented 7 years ago

I have not reproduced it. But I think it happens if you have other package.json root's in one of a subfolder (maybe cause some conflicts with those packages etc.?). I have not specified include or files first because I was not so familiar how to configure tsconfig for the webpack loader - I thought you must not specify the files/include config because I don't want to use typescript as builder quasi - but as default it just scans every sub folder no matter how complex/nested project structure you have. I think this breaks the neck of our poor guy.

However I think this shouldn't end in a fatal error. More informative information were better.

myknbani commented 7 years ago

@aight8 To me that's the difference maker.

{
    "compilerOptions": {
        "module": "commonjs",
        "moduleResolution": "node",
        "target": "es2016",
        "noImplicitAny": false,
        "sourceMap": true,
        "strictNullChecks": true,
        "importHelpers": true,
        "allowJs": true,
        "rootDir": "src",
        "jsx": "react",
        "lib": [
            "dom",
            "es2016"
        ]
    },
    // "include": [
    //     "src",
    //     "typedefs"
    // ],
    "exclude": [
        "src/frontend"
    ]
}

Commenting out the "include" portion yields

...

FATAL ERROR: CALL_AND_RETRY_LAST Allocation failed - JavaScript heap out of memory
 1: node::Abort() [node]
 2: 0xfac98c [node]

while having the "include" configuration compiles my project in a few seconds.

myknbani commented 7 years ago

by the way, this is not through webpack and ts-loader, this is my backend to be run by Node.

sandersn commented 7 years ago

[Summary for those who find this issue via Google.] [Edit: More detailed workaround-debugging instructions] [Edit: I wrote a more detailed guide.]

Previous bugs like this have all been caused by trying to compile large Javascript libraries in node_modules when allowJs: true. Typescript shouldn't run out of memory on these libraries, but sometimes it does, particularly as we add more advanced analysis of like flow control. These analyses often work on unannotated code, which of course means that large Javascript libraries stress them the most.

While you're waiting for us to fix these bugs, here's how to find a workaround:

  1. Do you have "allowJs": true? Turn it off. Does compilation complete? There may be lots of errors, but if there is no crash, then the culprit is the compiler getting stuck on Javascript code.
    1. Install typings for libraries you use. The compiler will stop looking as soon as it sees the .d.ts and won't even try to process .js or .ts files.
    2. Specifically "exclude" node_modules or "include" your source directory. This will help the compiler to know that it doesn't need to process every library you depend on.
  2. Do you have "noImplicitAny": true? Turn it off. If compilation completes, then advanced analysis is the culprit.
    • Try adding more type annotations inside function bodies (especially large functions) before turning noImplicitAny back on. This will let the compiler skip some of its advanced inference. The oo-memory bugs I've seen in the last year have all been triggered by inference (either from control flow or for type arguments).

Finally, if you can share your project with us, it raises the probability we can fix the bug. A miniature repro is even better, of course, but that is difficult with crash bugs.

pltnkv commented 7 years ago

@RyanCavanaugh try run this code in https://www.typescriptlang.org/play/

enum SlideName {
    FIRST_LOGIN_WELCOME,
    ADD_CONTENT,
    ADD_NOTES,
    NAVIGATE,
    INVITE_COLLABORATORS,
    FIRST_LOGIN_CONGRATS,
    INVITE_WELCOME,
    WORK_IN_REALTIME,
    COMMENT,
    FRAMES,
    COMMUNICATE,
    FIRST_LOGIN_FULL_WELCOME,
    VISIT_DASHBOARD,
    UPDATES,
    UNGROUP
}
let slides:any[] = []
slides[SlideName.FIRST_LOGIN_WELCOME] = {
    caption: 'Let us show you around!'
}
slides[SlideName.ADD_CONTENT] = {
    caption: 'Add content'
}
slides[SlideName.ADD_NOTES] = {
    caption: 'Add notes'
}
slides[SlideName.NAVIGATE] = {
    caption: 'Use the mini-map'
}
slides[SlideName.INVITE_COLLABORATORS] = {
    caption: 'Invite collaborators'
}
slides[SlideName.FIRST_LOGIN_CONGRATS] = {
    caption: 'Congrats!'
}
slides[SlideName.INVITE_WELCOME] = {
    caption: '4 quick collaboration tips'
}
slides[SlideName.WORK_IN_REALTIME] = {
    caption: 'Work in real-time'
}
slides[SlideName.COMMENT] = {
    caption: 'Comment'
}
slides[SlideName.FRAMES] = {
    caption: 'Create frames'
}
slides[SlideName.COMMUNICATE] = {
    caption: 'Communicate'
}
slides[SlideName.FIRST_LOGIN_FULL_WELCOME] = {
    caption: 'Let us show you around!'
}
slides[SlideName.VISIT_DASHBOARD] = {
    caption: 'Visit your Dashboard'
}
slides[SlideName.UPDATES] = {
    caption: 'Updates'
}
slides[SlideName.UNGROUP] = {
    caption: 'Ungroup or Lock'
}

Browser will crash or you will get FATAL ERROR: CALL_AND_RETRY_LAST Allocation failed - process out of memory in tsc

sandersn commented 7 years ago

Thanks for the minified repro. For me, this example freezes the playground on Chrome, but I can't get it to crash tsc. Here's what I did:

  1. Paste example into index.ts
  2. npm init with all defaults
  3. npm install --save-dev typescript@2.2.1
  4. ./node_modules/typescript/bin/tsc index.ts

I also tried with 2.2.3 and the latest commit from master. None of them ran out of memory.

I'll try to debug using the playground, but in the meantime can you confirm that you can repro the oo-memory crash with tsc from a clean directory?

sandersn commented 7 years ago

On my machine, if I paste in { caption } entries one at a time, things get really slow between items 10 and 11. (FRAMES and COMMUNICATE)

sandersn commented 7 years ago

The playground is running 2.1.4-insiders.20161201. I tried with tsc 2.1.5 and and 2.1.7 and still couldn't repro.

pltnkv commented 7 years ago

I'm sorry being misleading you. I used typescript@2.2.1 with webpack1 and ts-loader@2.0.1 Some steps for repro:

add tsconfig.json

{
  "compilerOptions": {
    "experimentalDecorators": true,
    "baseUrl": "./",
    "target": "ES6"
  }
}

add webpack.config.js

module.exports = {
        entry: './index.ts',
        output: {
            filename: 'res.js'
        },
        resolve: {
            extensions: ['', '.ts', '.tsx', '.js'],
        },
        module: {
            loaders: [
                {
                    test: /\.tsx?$/,
                    loader: 'ts-loader'
                }
            ],
        },
        ts: {
            transpileOnly: true,
            compilerOptions: {
                target: 'ES5',
                jsx: 'react',
                sourceMap: false
            }
        },
    }
  1. Paste example into index.ts
  2. npm init with all defaults
  3. npm install --save-dev typescript@2.2.1
  4. npm install --save-dev ts-loader
  5. webpack
sandersn commented 7 years ago

Yep, here's a pretty nice exponential curve: image The last two, 14 and 15, just run out of memory.

typescript@next has the same behaviour.

sandersn commented 7 years ago

I'm still tracking down the cause of this bug, but I discovered that the repro problem is the same as #12735, which also used webpack. transpileOnly: true doesn't initialize the typescript compiler correctly, such that the Array type doesn't get included, which means that in let slides: any[] = [], : any[] is ignored.

That means the compiler tries to use its expanding array type inference. That's where the exponential bug is, just like in #12735.

Workaround

In webpack.config.js, set transpileOnly: false. This correctly initialises the compiler.

To repro without webpack

use this tsconfig:

{
    "compilerOptions": {
        "experimentalDecorators": true,
        "baseUrl": "./",
        "target": "ES6",
        "noImplicitAny": true
    },
    "files": [
        "index.ts"
    ]
}

Remove the type annotation from the declaration of slides:

let slides = [];

As the figure above shows, you can control the exponential behaviour by varying the number of assignments.

sandersn commented 7 years ago

This looks a lot like #12946 actually.

pltnkv commented 7 years ago

Thank you, I already removed the type annotation. But we can't use workaround transpileOnly: false, because compilcation in webpack is very very slow in watch mode. And transpileOnly: true is very convenient for dev mode (for fast prototyping without strong typings).

sandersn commented 7 years ago

Well, the bug occurs when webpack incorrectly initialises the compiler such that (1) the Array type is missing and (2) noImplicitAny: true; then it tries to compile a program that (3) has multiple assignments to (4) a variable initialised with an empty array. This leads to the following workarounds:

  1. Make sure the Array type is present via transpileOnly: false or by fixing webpack (ts-loader?) so that transpileOnly: true uses the compiler correctly.
  2. Set noImplicitAny: false in the webpack config. But this didn't work for me, so it probably interferes with transpileOnly: true.
  3. Use only a single assignment, probably changing the structure to something like
let slides = {
  [SlideName.FIRST_LOGIN_WELCOME]: 'Let us show you around!',
  // ...
}
  1. Initialise slides to something besides an empty array, then overwrite the first entry:
let slides = [{ caption: 'Work around Typescript bug' }]

Since (1) doesn't work for you, I'd probably recommend (4) since it's the most obvious and can be removed once you get a version with the bug fixed.

sandersn commented 7 years ago

Fix is up at #15075

k8w commented 7 years ago

2.3.3 still get this

sandersn commented 7 years ago

@twoeo can you provide more detail? Check out the guide I wrote and if that doesn't solve your problem then open a bug for your crash.

Opty1712 commented 7 years ago

Got the same error on ts 2.2.2 or 2.3.1 / ts-loader or awesome-typescript-loader / UNIX or Win7. Error appears only while running tests on karma. About 50 tests pass, but about 60 crush.

When I look at task manager, I see that node.exe takes about 1.9GB of ROM at this moment. Found some info that V8 JS engine allows only 1.7GB ROM for usage. May be there is a way to preprocess and/or process files not all at one moment and keep everything in memory, but 5 or 10 files?

Here is my karma config

const webpack = require('webpack'); const autoprefixer = require('autoprefixer');

module.exports = (config) => { config.set({ browsers: ['Chrome'], singleRun: true, concurrency: Infinity, autoWatch: false, frameworks: ['jasmine'], plugins: [ 'karma-sourcemap-loader', 'karma-webpack', 'karma-jasmine', 'karma-remap-istanbul', 'karma-coverage', 'karma-chrome-launcher', 'karma-spec-reporter' ],

files: [
  'node_modules/babel-polyfill/dist/polyfill.js',
  'src/**/*.spec.*'
],

preprocessors: {
  'src/**/*.spec.*': ['webpack', 'sourcemap'],
},

reporters: ['karma-remap-istanbul', 'spec'],

webpackMiddleware: {
  stats: 'errors-only',
  noInfo: true,
},

remapIstanbulReporter: {
  src: 'coverage/coverage-final.json',
  reports: {
    lcovonly: 'coverage/lcov.info',
    html: 'coverage/report',
    'text-summary': '',
  },
  fixWebpackSourcePaths: true,
},

autoWatchByDelay: 3000,

level: 'debug',

webpack: {
  devtool: 'source-map',
  module: {
    rules: [
      {
        test: /\.tsx$/,
        loader: 'awesome-typescript-loader',
      }, {
        test: /\.tsx$/,
        loader: 'istanbul-instrumenter-loader',
        enforce: 'post',
        options: {
          esModules: true,
        },
      },
      {
        test: /\.css$/,
        use: [
          { loader: 'style-loader' },
          { loader: 'css-loader' },
          {
            loader: 'postcss-loader',
            options: {
              plugins: () => [autoprefixer('ie >= 11')],
            },
          }
        ],
      },
      {
        test: /\.svg|ico|png|gif|jpg|scss|eot|ttf|woff|woff2($|\?)/,
        loader: 'null-loader',
      }
    ],
  },
  resolve: {
    extensions: ['.js', '.ts', '.tsx', '.css', '.scss', '.png'],
  },
  plugins: [
    new webpack.SourceMapDevToolPlugin({
      filename: null,
      test: /\.tsx($|\?)/i,
    })
  ],
  externals: {
    cheerio: 'window',
    'react/addons': true,
    'react/lib/ExecutionEnvironment': true,
    'react/lib/ReactContext': true,
  },
},

}); };

taoqf commented 7 years ago

I came to the same isusse using typescript@2.5.0-dev.20170707 and gulp-typescript@3.2.0 tsc works fine.

Opty1712 commented 7 years ago

If someone has the same propblem check how do you pass files to karma. If you use something like this src/**/*.spec.* you will have a problem like mine. the correct way to call files is var testsContext = require.context(".", true, /_test$/); testsContext.keys().forEach(testsContext); Taken from https://webpack.github.io/docs/usage-with-karma.html#alternative-usage

sandersn commented 7 years ago

@taoqf Can you provide more detail on your crash? Check out the guide I wrote and if that doesn't solve your problem then open a bug for your crash since the cause is almost certainly different from this one.

taoqf commented 7 years ago

OS: Debian Node.js: v8.1.3 gulpfile.js

gulp.task('compile-ts', () => {
    const ts = require('gulp-typescript');
    const tsProject = ts.createProject('./tsconfig.json');
    tsProject.options.module = 1;
    const dest = tsProject.options.outDir;
    return gulp.src('./src/**/*.ts')
        .pipe(tsProject())
        .pipe(gulp.dest(dest));
});

Exception i got:

<--- Last few GCs --->

[24442:0x2def9d0]    58440 ms: Mark-sweep 1400.1 (1465.9) -> 1400.1 (1465.9) MB, 1948.3 / 0.0 ms  allocation failure GC in old space requested
[24442:0x2def9d0]    60312 ms: Mark-sweep 1400.1 (1465.9) -> 1400.1 (1434.9) MB, 1871.6 / 0.0 ms  last resort 
[24442:0x2def9d0]    62184 ms: Mark-sweep 1400.1 (1434.9) -> 1400.0 (1434.9) MB, 1871.8 / 0.0 ms  last resort 

<--- JS stacktrace --->

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

Security context: 0x3d1f48829891 <JS Object>
    2: write [/home/taoqf/feidao/temp/boai-h5-6/1/node_modules/typescript/lib/typescript.js:~9035] [pc=0x3cfdedb6fe70](this=0x1857e443e689 <an Object with map 0xddd4399bc9>,s=0x3c6749682c29 <String[4]: "id">)
    3: pipelineEmitExpression [/home/taoqf/feidao/temp/boai-h5-6/1/node_modules/typescript/lib/typescript.js:~66807] [pc=0x3cfdedbd085f](this=0xf51a038dbf9 <JS Global Object>,node=0x29110b...

FATAL ERROR: CALL_AND_RETRY_LAST Allocation failed - JavaScript heap out of memory
 1: node::Abort() [gulp]
 2: 0x13647ec [gulp]
 3: v8::Utils::ReportOOMFailure(char const*, bool) [gulp]
 4: v8::internal::V8::FatalProcessOutOfMemory(char const*, bool) [gulp]
 5: v8::internal::Factory::NewFillerObject(int, bool, v8::internal::AllocationSpace) [gulp]
 6: v8::internal::Runtime_AllocateInTargetSpace(int, v8::internal::Object**, v8::internal::Isolate*) [gulp]
 7: 0x3cfded28437d
Aborted
taoqf commented 7 years ago

@sandersn Thanks, I have checked the guide list and could not solve my problem.

sandersn commented 7 years ago

@taoqf can you open a new issue? The cause is almost certainly different from this bug.

sandersn commented 7 years ago

Also, do you depend on fp-ts, fantasyland or monet? Those libraries are known to have problems running out of memory. (See #16029 or #16777)

SamuelGustafsson commented 6 years ago

I had this problem when I used: "typescript": "^2.6.2", "awesome-typescript-loader": "^3.4.1", "webpack": "^3.10.0",

So I switched awesome-typescript-loader to ts-loader and then it worked.

ccorcos commented 6 years ago

I had this issue and I fixed it by commenting out the line below...

import {
    getTrelloBoardsInput,
    getTrelloBoardsOutput,
} from "../../server/apis/getTrelloBoards"
// export { getTrelloBoardsInput, getTrelloBoardsOutput }
xskif commented 6 years ago

add to the package.json -> scripts

"webpack-dev-server": "node --max_old_space_size=4096 --optimize_for_size --stack_size=4096 ./node_modules/.bin/webpack-dev-server"

cafesanu commented 6 years ago

Adding transpileOnly: true and using fork-ts-checker-webpack-plugin (https://github.com/TypeStrong/ts-loader#loader-options) instead, solved my issue.

ekulabuhov commented 6 years ago

@sandersn Thank you for your detailed guide! Does "Install typings for libraries you use." advice still applicable if we use typeAcquisition.enable: true?

sandersn commented 6 years ago

@ekulabuhov I think automatic type acquisition only works for javascript projects. My advice is for Typescript projects.

Is your project purely javascript? If so, consider opening a new issue because this one has been fixed for almost a year.

ekulabuhov commented 6 years ago

@sandersn it's a mixed project. We've enabled allowJs: true recently. That caused the tsc to crash with out of memory exception. We had node_modules excluded already. So we specified which folders to include and it solved our problem.

GalitTugi commented 6 years ago

I have the same issue at my project. Isolated the prop that caused it - which was using webpack's EvalSourceMapDevToolPlugin (Also happens with SourceMapDevToolPlugin). I really need this option though - For debugging. Did anybody else handle this situation?

giniedp commented 6 years ago

i use the NODE_OPTIONS env variable to give all node tools more headroom

export NODE_OPTIONS=--max-old-space-size=4096
GalitTugi commented 6 years ago

This is what I did (through the test option in the run command), but is that a real solution? It sounds like a patch to a larger issue. What if my tests and project keep on growing and that number won't be enough? It feels like there's a real issue with karma using source mapping for debugging, allocating more memory might solve that that issue now, but doesn't really work as a long term solution...

giniedp commented 6 years ago

no, its not a final solution. My team is also suffering from this issue and had to increase the max old space size several times now. This week we are upgrading to Webpack 4 and testing the performance. So far the results are very promising.

GalitTugi commented 6 years ago

Wow, gtk! I'll try to check it out and promote it in our team as well. Thanks!