Description
This bug report is a follow-up to this tweet where I write about OOM crashes in 3.9.1-rc. @DanielRosenwasser asked me to report an issue, but I find it really hard to narrow it down.
I have a project with ~2k lines of code. It uses another internal package with ~18k lines of code. The problem is that the compiler doesn't terminate anymore. I then tried to compile a subset of the project (which is a recursive decent parser, BTW), which runs in under 6 seconds. If I add more and more files, it will get slower and slower to a point where it will run into OOM. The interesting thing is that there's no big bump in files, lines, types, instantiations or symbols:
Files: 1588 1597 1600
Lines: 65199 80674 81049
Nodes: 278678 349628 350339
Identifiers: 90620 91032 91288
Symbols: 64556 465900 478162
Types: 3027 109800 134328
Instantiations: 31435 115295 222586
Memory used: 125785K 295562K 952063K
I/O read: 0.19s 0.13s 0.90s
I/O write: 0.02s 0.05s 0.06s
Parse time: 3.78s 3.27s 4.77s
Bind time: 0.80s 0.78s 1.07s
Check time: 0.96s 5.37s 94.43s
Emit time: 0.25s 0.74s 0.77s
Total time: 5.79s 10.15s 101.04s
Yes, there are twice as many instantiations, which I assume results from the use of rather large discriminated unions (.e.g when restructuring them), but the increase in memory is almost three times as high. The CPU profile when compiling looks like this:
My current guess is that the exponential increase is somehow related to Instantiations ⨉ Instantiations, as most of the time is spent in someTypeRelatedToType
.
I tried breaking it down to a reproducible case, but as the project with which I'm experiencing this issue is not Open Source, stripping everything down takes too much time. I understand that this is not an actionable error report, but maybe there's an obvious reason why this recent change in behavior may be causing this. If not, feel free to close it
TypeScript Version: 3.9.1-rc
Search Terms: crash, out of memory, oom
Code
Could not be provided
Expected behavior:
TypeScript compiles the code
Actual behavior:
TypeScript runs out of memory
UPDATE:
I managed to get all packages to build with 3.9.1 by removing mapped discriminated union types, i.e. functions with signatures like function<T extends FooKind>(kind: T): FooLike<T>
, whereas FooLike<T>
uses conditionals to select a specific type from a huge union with ~1k types. Build times now are:
package-c 3.8.3 3.9.1
Files: 1626 1628
Lines: 84005 84000
Nodes: 357333 357139
Identifiers: 93411 93314
Symbols: 488307 487405
Types: 128763 124300
Instantiations: - 167777
Memory used: 1092025K 979008K
I/O read: 0.17s 0.33s
I/O write: 0.13s 0.22s
Parse time: 3.29s 5.44s
Bind time: 1.20s 1.64s
Check time: 60.46s 92.90s
Emit time: 2.41s 2.85s
Total time: 67.37s 102.82s
package-b 3.8.3 3.9.1
Files: 1588 1590
Lines: 64154 64149
Nodes: 276974 276780
Identifiers: 89681 89584
Symbols: 64608 64983
Types: 3484 3621
Instantiations: - 9232
Memory used: 131259K 130999K
I/O read: 0.25s 0.22s
I/O write: 0.10s 0.08s
Parse time: 4.70s 4.62s
Bind time: 0.99s 1.14s
Check time: 0.99s 1.12s
Emit time: 1.16s 1.38s
Total time: 7.83s 8.26s
package-a 3.8.3 3.9.1
Files: 1577 1579
Lines: 115025 115020
Nodes: 329307 329113
Identifiers: 88729 88632
Symbols: 154484 151390
Types: 45980 45135
Instantiations: - 36085
Memory used: 372082K 274693K
I/O read: 0.27s 1.54s
I/O write: 3.98s 3.98s
Parse time: 6.17s 7.64s
Bind time: 1.63s 1.77s
Check time: 21.55s 4.72s
Emit time: 13.94s 15.12s
Total time: 43.29s 29.25s