Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

JavaScript heap out of memory for 10s of MB of source #17112

Open
taoqf opened this issue Jul 12, 2017 · 30 comments
Open

JavaScript heap out of memory for 10s of MB of source #17112

taoqf opened this issue Jul 12, 2017 · 30 comments
Labels
Bug A bug in TypeScript
Milestone

Comments

@taoqf
Copy link

taoqf commented Jul 12, 2017

TypeScript Version: 2.4.1 / nightly (2.5.0-dev.20170707)

Code
gulpfile.js

// A *self-contained* demonstration of the problem follows...
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));
});

tsconfig.json

{
        "include": [
                "src"
        ],
        "compilerOptions": {
                "module": "commonjs",
                "target": "esnext",
                "noImplicitAny": false,
                "sourceMap": false,
                "emitDecoratorMetadata": true,
                "experimentalDecorators": true,
                "strictNullChecks": false,
                "noImplicitThis": true,
                "rootDir": "./src/",
                "rootDirs": [],
                "allowJs": false,
                "allowUnreachableCode": false,
                "allowUnusedLabels": false,
                "alwaysStrict": true,
                "baseUrl": "",
                "charset": "utf8",
                "declaration": false,
                "inlineSourceMap": false,
                "allowSyntheticDefaultImports": false,
                "diagnostics": false,
                "emitBOM": false,
                "forceConsistentCasingInFileNames": false,
                "importHelpers": false,
                "inlineSources": false,
                "isolatedModules": false,
                "lib": [
                        "es6",
                        "es7",
                        "dom"
                ],
                "listFiles": true, // default false
                "listEmittedFiles": true, // default false
                "locale": "zh_CN",
                "newLine": "CRLF",
                "noEmit": false,
                "moduleResolution": "node",
                "noEmitHelpers": false,
                "noEmitOnError": false,
                "noImplicitReturns": false,
                "noImplicitUseStrict": false,
                "maxNodeModuleJsDepth": 0,
                "noLib": false,
                "outDir": "./dist/",
                "noFallthroughCasesInSwitch": false,
                "noResolve": false,
                "noUnusedLocals": false,
                "noUnusedParameters": false,
                "paths": {},
                "preserveConstEnums": false,
                "pretty": true,
                "removeComments": false,
                "skipDefaultLibCheck": true, // default false
                "skipLibCheck": true, // default false
                "stripInternal": false,
                "suppressExcessPropertyErrors": false,
                "suppressImplicitAnyIndexErrors": true, // default false
                "traceResolution": true, // default false
                "typeRoots": [],
                "types": [],
                "watch": false
        }
}

Expected behavior:

Actual behavior:
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

More

@taoqf
Copy link
Author

taoqf commented Aug 3, 2017

@sandersn , Could this be fixed?

@sandersn sandersn self-assigned this Aug 3, 2017
@sandersn
Copy link
Member

sandersn commented Aug 3, 2017

Two questions:

  1. Can you provide the code or a small repro?
  2. The gulp-typescript setup changes options.module=1. Does tsc still succeed when you set the equivalent module option in tsconfig? It's commonjs right now and I'm not sure that 1 means commonjs

Afterwards, if tsc still works, then it sounds like a gulp-typescript bug. The stack is in emit when it runs out of memory. This is very unusual for vanilla tsc, so I would first suspect a configuration/setup bug in gulp-typescript.

Also, @rbuckton, does that crash location mean anything to you?

@taoqf
Copy link
Author

taoqf commented Aug 4, 2017

1 means comonjs 2 amd 3 umd
I set options.module=1 this because i have multi tasks in gulp.
I guess gulp may use more memory than tsc because it will store files in memory steam.
I have tested if I reduce the number of the file it will succeed.

@DanielRosenwasser DanielRosenwasser added the Needs More Info The issue still hasn't been fully clarified label Aug 4, 2017
@mhegazy
Copy link
Contributor

mhegazy commented Aug 16, 2017

looks like the gulp typescript + typescript memory usage pushes you over the limit. I would say gulp-typescript should take the first stab at this issue.

@mhegazy mhegazy added External Relates to another program, environment, or user action which we cannot control. and removed Needs More Info The issue still hasn't been fully clarified labels Aug 16, 2017
@taoqf
Copy link
Author

taoqf commented Aug 17, 2017

@mhegazy , I got this Error just now:

<--- Last few GCs --->

[22042:0x3696020]    34073 ms: Mark-sweep 1403.3 (1447.3) -> 1403.3 (1442.3) MB, 877.7 / 0.0 ms  (+ 0.0 ms in 0 steps since start of marking, biggest step 0.0 ms, walltime since start of marking 878 ms) last resort 
[22042:0x3696020]    34966 ms: Mark-sweep 1403.3 (1442.3) -> 1403.3 (1442.3) MB, 891.5 / 0.0 ms  last resort 


<--- JS stacktrace --->

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

Security context: 0x2a16e0b9cef1 <JSObject>
    1: declareSymbol [/home/taoqf/.nvm/versions/node/v8.4.0/lib/node_modules/typescript/lib/tsc.js:~18571] [pc=0x1b65f5d1bf8b](this=0x3f86308890d9 <JSGlobal Object>,symbolTable=0x10f596065381 <Map map = 0x17f790d183b9>,parent=0x220cdb20d551 <Symbol map = 0x17f790d19019>,node=0x14238561b021 <Node map = 0x17f790d14e19>,includes=4,excludes=0)
    2: bindPropertyOrMethodOrAccessor [/home/taoqf/.nvm/...

FATAL ERROR: CALL_AND_RETRY_LAST Allocation failed - JavaScript heap out of memory
 1: node::Abort() [node]
 2: 0x13740dc [node]
 3: v8::Utils::ReportOOMFailure(char const*, bool) [node]
 4: v8::internal::V8::FatalProcessOutOfMemory(char const*, bool) [node]
 5: v8::internal::Factory::NewFillerObject(int, bool, v8::internal::AllocationSpace) [node]
 6: v8::internal::Runtime_AllocateInTargetSpace(int, v8::internal::Object**, v8::internal::Isolate*) [node]
 7: 0x1b65f58040dd
[1]    22042 abort      tsc

using tsc.

@mhegazy
Copy link
Contributor

mhegazy commented Aug 17, 2017

can you share your project

@mhegazy mhegazy added Bug A bug in TypeScript and removed External Relates to another program, environment, or user action which we cannot control. labels Aug 17, 2017
@mhegazy mhegazy modified the milestone: TypeScript 2.6 Aug 17, 2017
@swlee60
Copy link

swlee60 commented Aug 22, 2017

+1

I have same problem.
I can't share my project because our enterprise project.
This is not appear in normal compile environment, but almost appear in below environment.

  1. large or huge size project
  2. If you change the file frequently during typescript compile (with hot module replacement), a crash appears.

@sandersn
Copy link
Member

sandersn commented Aug 24, 2017

@taoqf @swlee60 can you try typescript@next ? The recent change #17984 improved checker resource usage for recursive types references. (eg class List<T> { map<U>(f): List<U> }). This doesn't directly address the problem of huge projects, but it's likely to help since huge projects typically have some specialised collections somewhere.

If that doesn't help, is there some way you can share your project? I don't have any other starting point for debugging since eliminating gulp-typescript from the crash. I can sign an NDA if needed.

@swlee60
Copy link

swlee60 commented Aug 25, 2017

@sandersn
I used typescript@next but problem still appears.
Problems occur on both sides of awesome-type-script-loader and ts-loader

$ tsc --version
Version 2.6.0-dev.20170824

PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
25546 ****** 20 0 2763m 1.5g 16m R 99.6 39.9 3:30.55 node

webpack: Compiling...

<--- Last few GCs --->

551020 ms: Mark-sweep 1288.8 (1408.1) -> 1288.8 (1412.1) MB, 876.2 / 0.0 ms [allocation failure] [GC in old space requested].
551884 ms: Mark-sweep 1288.8 (1412.1) -> 1288.8 (1412.1) MB, 864.3 / 0.0 ms [allocation failure] [GC in old space requested].
552797 ms: Mark-sweep 1288.8 (1412.1) -> 1297.8 (1408.1) MB, 912.2 / 0.1 ms [last resort gc].
553713 ms: Mark-sweep 1297.8 (1408.1) -> 1306.9 (1408.1) MB, 916.7 / 0.1 ms [last resort gc].

<--- JS stacktrace --->

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

Security context: 0x3f6911dcfb51
2: /* anonymous */ [/home1/irteam/dev/partner/booking-web/partner/node_modules/source-map/lib/source-node.js:~336] [pc=0x3c44f4a6f4a0] (this=0x3f6911de6119 ,chunk=0x2bbfebf8e701 <String[22]: \n font-size: 20px;>,original=0x235420ed6be1 <an Object with map 0x1c0b11e7f8d9>)
3: walk(aka SourceNode_walk) [/home1/irteam/dev/partner/booking-web/partner/node_modules/source...

FATAL ERROR: CALL_AND_RETRY_LAST Allocation failed - JavaScript heap out of memory
1: node::Abort() [/home1/irteam/apps/bin/node]
2: 0x1098b2c [/home1/irteam/apps/bin/node]
3: v8::Utils::ReportApiFailure(char const*, char const*) [/home1/irteam/apps/bin/node]
4: v8::internal::V8::FatalProcessOutOfMemory(char const*, bool) [/home1/irteam/apps/bin/node]
5: v8::internal::Factory::NewFixedArray(int, v8::internal::PretenureFlag) [/home1/irteam/apps/bin/node]
6: v8::internal::TypeFeedbackVector::New(v8::internal::Isolate*, v8::internal::Handlev8::internal::TypeFeedbackMetadata) [/home1/irteam/apps/bin/node]
7: 0xb47d40 [/home1/irteam/apps/bin/node]
8: 0xb480a9 [/home1/irteam/apps/bin/node]
9: 0xb4a4a0 [/home1/irteam/apps/bin/node]
10: 0xb51b46 [/home1/irteam/apps/bin/node]
11: v8::internal::Compiler::Compile(v8::internal::Handlev8::internal::JSFunction, v8::internal::Compiler::ClearExceptionFlag) [/home1/irteam/apps/bin/node]
12: v8::internal::Runtime_CompileLazy(int, v8::internal::Object**, v8::internal::Isolate*) [/home1/irteam/apps/bin/node]
13: 0x3c44e83092a7
Done in 554.33s.

@taoqf
Copy link
Author

taoqf commented Aug 25, 2017

@sandersn same here.

$ tsc --version
Version 2.6.0-dev.20170824
$ tsc

<--- Last few GCs --->

[26137:0x3b6b020]    37623 ms: Mark-sweep 1403.3 (1445.3) -> 1403.3 (1440.8) MB, 861.8 / 0.0 ms  (+ 0.0 ms in 0 steps since start of marking, biggest step 0.0 ms, walltime since start of marking 862 ms) last resort 
[26137:0x3b6b020]    38487 ms: Mark-sweep 1403.3 (1440.8) -> 1403.3 (1440.8) MB, 864.1 / 0.0 ms  last resort 


<--- JS stacktrace --->

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

Security context: 0xc3bfff9cef1 <JSObject>
    1: declareSymbol(aka declareSymbol) [/home/taoqf/.nvm/versions/node/v8.4.0/lib/node_modules/typescript/lib/tsc.js:~14980] [pc=0xac3a15e8497](this=0xc3bfff82241 <undefined>,symbolTable=0x1eb8b183ecc9 <Map map = 0x4a1246983b9>,parent=0x29b2e1ed5e61 <Symbol map = 0x4a12469a4b9>,node=0x2cc77d79521 <Node map = 0x4a124695a79>,includes=4,excludes=0,isReplaceableByMethod=0xc3bfff82241 <undefined>)
  ...

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

@estaub
Copy link

estaub commented Aug 25, 2017

@sandersn I'm totally ignorant of tsc internals, but I might have a thought worth chasing. If I understand it correctly, the fix you provided (PR #17984) seems incomplete, in at least a couple of ways:

  1. It doesn't (at least from your description) address constrained (extends) types.
  2. It doesn't address cycles of isomorphic generic-interface-containing-generic-method where the method also consumes the class's type parameters.

FWIW!!! I suspect these may be subcases of broader sets of unaddressed cases. In any event, my main reason for writing is to provoke you to think along these lines for missed cases. If you're not one yourself, you might want to consult a Typescript "language lawyer".

@weswigham
Copy link
Member

@swlee60 Out of curiosity, does your crash disappear if you disable sourcemaps (source-map is in your crash log, after all)?

@swlee60
Copy link

swlee60 commented Aug 25, 2017

@weswigham Do you mean webpack devtool option? Whether I set inline-source-map or eval, heap overflow always comes up.

@sandersn
Copy link
Member

sandersn commented Sep 1, 2017

Interesting. Looks like @taoqf's project runs out of memory in the binder. Not much has changed in the binder recently, though.

@sandersn
Copy link
Member

sandersn commented Sep 1, 2017

@taoqf, what is the version of Typescript that you used before 2.4.1? Your project fails on 2.3 for me as well.

@sandersn
Copy link
Member

sandersn commented Sep 1, 2017

On master (I haven't checked with 2.3 or 2.4), the AST alone brings memory usage to 1.1 GB, which means that every byte of source results in almost 40 bytes in the parse tree. That leaves the compiler about 300 MB to bind and check with. It is unable to do so.

We need to think about architectural ways to reduce parse tree overhead to make sure that Typescript can scale to very large projects. Specifically, how much overhead we incur when parsing common patterns like object literals.

As a workaround, @taoqf, can you split your compilation into multiple compilations? Then you could compile it in multiple pieces. You can use .d.ts files, either generated or manually created, as interfaces between the split compilations.

@taoqf
Copy link
Author

taoqf commented Sep 2, 2017

@taoqf, what is the version of Typescript that you used before 2.4.1?

I always used next version.

@tiger-seo
Copy link

<--- Last few GCs --->

   64156 ms: Mark-sweep 1302.7 (1435.3) -> 1298.6 (1435.3) MB, 2648.5 / 0.0 ms [allocation failure] [GC in old space requested].
   66567 ms: Mark-sweep 1298.6 (1435.3) -> 1298.6 (1435.3) MB, 2411.3 / 0.0 ms [allocation failure] [GC in old space requested].
   69175 ms: Mark-sweep 1298.6 (1435.3) -> 1306.1 (1409.3) MB, 2607.0 / 0.0 ms [last resort gc].
   71539 ms: Mark-sweep 1306.1 (1409.3) -> 1313.8 (1409.3) MB, 2363.7 / 0.0 ms [last resort gc].


<--- JS stacktrace --->

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

Security context: 0x2dd8a203fa99 <JS Object>
    1: set [native collection.js:~252] [pc=0x27ff7fb0d83b] (this=0x3c34b6f24d71 <a Map with map 0x230c6e7113b1>,r=0x1039b0b29051 <String[13]: 896958,897404>,z=0x1039b0b29079 <a TypeObject with map 0x230c6e796f31>)
    2: getTypeWithThisArgument [/home/jenkins/workspace/Project/web-app/node_modules/typescript/lib/typescript.js:~31577] [pc=0x27ff7fbe98bc] ...

FATAL ERROR: CALL_AND_RETRY_LAST Allocation failed - JavaScript heap out of memory
 1: node::Abort() [@angular/cli]
 2: 0x10d368c [@angular/cli]
 3: v8::Utils::ReportApiFailure(char const*, char const*) [@angular/cli]
 4: v8::internal::V8::FatalProcessOutOfMemory(char const*, bool) [@angular/cli]
 5: v8::internal::Factory::NewFixedArray(int, v8::internal::PretenureFlag) [@angular/cli]
 6: v8::internal::OrderedHashTable<v8::internal::OrderedHashMap, v8::internal::JSMapIterator, 2>::Allocate(v8::internal::Isolate*, int, v8::internal::PretenureFlag) [@angular/cli]
 7: v8::internal::OrderedHashTable<v8::internal::OrderedHashMap, v8::internal::JSMapIterator, 2>::Rehash(v8::internal::Handle<v8::internal::OrderedHashMap>, int) [@angular/cli]
 8: v8::internal::OrderedHashTable<v8::internal::OrderedHashMap, v8::internal::JSMapIterator, 2>::EnsureGrowable(v8::internal::Handle<v8::internal::OrderedHashMap>) [@angular/cli]
 9: v8::internal::Runtime_MapGrow(int, v8::internal::Object**, v8::internal::Isolate*) [@angular/cli]
10: 0x27ff7e2060c7

@sandersn
Copy link
Member

sandersn commented Sep 5, 2017

@tiger-seo can you open a new issue? There are multiple reasons for the compiler to run out of memory and your reason is likely different from @taoqf.

@sandersn
Copy link
Member

sandersn commented Sep 5, 2017

@taoqf if compilation worked previously, what else changed? Did your project add a lot more files? Did the individual files get a lot bigger? The project you gave me fails on 2.3, 2.4 and 2.5 and I expect it would fail on earlier versions because the AST memory footprint hasn't grown much recently.

@taoqf
Copy link
Author

taoqf commented Sep 5, 2017

It never worked , I compiled in multiple pieces in my project now.

@taoqf
Copy link
Author

taoqf commented Sep 8, 2017

@sandersn , I tried to use gulp-typescript and --max-old-space-size=4096 to run script, it will be ok, it would be very nice if tsc and gulp-typescript could accept this option.

@troeggla
Copy link

troeggla commented Sep 9, 2017

I recently ran into the same issue using ts-loader and webpack after upgrading Typescript from 2.3.4 to 2.5.2. I downgraded to 2.4.2 and 2.4.1 and the issue persisted. With 2.4.0, however, everything works as expected.

@sandersn
Copy link
Member

@troeggla How big is your project? If the project is less than 10 MB of source, then it's probably a different cause.

Can you

  1. Try building with typescript@next?
  2. If it still fails, open a separate issue.
  3. Share your source with us? I can sign an NDA if necessary.

@pocesar
Copy link

pocesar commented Sep 12, 2017

Randomly getting this on my project (using nightly, tsc in watch mode), not sure how to reproduce, it just happens sometimes. 7GB/8GB of RAM ATM, but plenty of swap and pagefile (9GBish)

07:28:49 - File change detected. Starting incremental compilation...



<--- Last few GCs --->

[1592:000002842FE68000]  7027823 ms: Mark-sweep 1401.5 (1465.4) -> 1401.5 (1465.4) MB, 4599.6 / 0.0 ms  last resort


<--- JS stacktrace --->

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

Security context: 0000033CF2C1CEA9 <JSObject>
    1: set [native collection.js:~247] [pc=000000C2A8FE6697](this=000000F425FBE6F1 <Map map = 000003AA6FD983B9>,p=000003A9ED17AB21
<String[9]: @Telefone>,x=000003A9ED17AB51 <Type map = 000003AA6FDC6CF9>)
    2: getLiteralType(aka getLiteralType) [C:\nodejs\node_modules\typescript\lib\tsc.js:~24883] [pc=000000C2A8D93E76](this=0000033C
F2C02241 <undefined>,value=000000CEC1A9C961 <String[8]: Telef...

FATAL ERROR: CALL_AND_RETRY_LAST Allocation failed - JavaScript heap out of memory
The terminal process terminated with exit code: 3

project is not too big, 36 typescript files, but only 120kb in total

@troeggla
Copy link

@sandersn Thanks for looking into this! Yeah, my project is well below 10 MB (excluding packages though) and the resulting bundle comes to about 1.9MB (without minification). Building with typescript@next compiles as it did with Typescript 2.4.0.

If you want, I can give you access to a private repository.

@sandersn
Copy link
Member

@troeggla If the nightly typescript is working for you then I think the recent bug fixes apply and we don't need your source.

@pocesar Can you open a separate issue? For only 120k of source you do not have the same issue as @taoqf.

Total RAM doesn't make a difference unless you have configured node to use more than 1.4 GB. You can try raising it to see if the problem goes away, and try lowering it to see if you can make it reproduce reliably. I think the flag is --max-old-space-size=8192 (for 8 GB).

You can also try compiling with --diagnostics to get a count of types and symbols. More than half a million types is a suspicious number.

@cheerun
Copy link

cheerun commented Sep 22, 2017

@sandersn
Hello, When do you think this problem will be solved?

My team also has large project, and we changed and fixed TypeScript version to 2.4.0 because upper TS 2.4.1 caused this FATAL ERROR: CALL_AND_RETRY_LAST Allocation failed - JavaScript heap out of memory issue.

We want to use awesome latest TypeScript's features, like 2.5, 2.6, ... or 3.0 and later! But we don't know when is this problem solved, so we can't upgrade TypeScript anymore.

If you can, please let me know the progress of this issue.

@sandersn
Copy link
Member

@cheerun Try typescript@next. We have fixed all but a two of the known issues there, and those fixes will also ship with 2.5.3.

If you have 10s of megabytes of source then you may still have a problem; that's what this issue tracks.

@sandersn sandersn changed the title FATAL ERROR: CALL_AND_RETRY_LAST Allocation failed - JavaScript heap out of memory JavaScript heap out of memory for 10s of MB of source Oct 4, 2017
@mhegazy mhegazy modified the milestones: TypeScript 2.6, Future Oct 9, 2017
@mhegazy
Copy link
Contributor

mhegazy commented Oct 9, 2017

The OP seems to be caused by a large object structure, @sandersn's comment in #17112 (comment) summarizes the issues.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Bug A bug in TypeScript
Projects
None yet
Development

No branches or pull requests

12 participants