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

FATAL ERROR out of memory after using 2.8GB RAM (convertPathData, defaultoption) #954

Closed
JoKalliauer opened this issue May 6, 2018 · 19 comments

Comments

@JoKalliauer
Copy link

JoKalliauer commented May 6, 2018

Prozessing the olderst version of File:Germany (+districts +municipalities) location map.svg (~73MB) fails afer needing more than 2,8GB RAM (I have 16GB RAM total, and during processing always more than 8GB free)

$ svgo -i "20180507223736!Germany_(+districts_+municipalities)_location_map_2013.svg" -o output.svg

<--- Last few GCs --->

[14628:000001C5D93EBC40]  1345238 ms: Mark-sweep 1384.2 (1457.6) -> 1384.1 (1458.1) MB, 3403.4 / 0.0 ms  allocation failure GC in old space requested
[14628:000001C5D93EBC40]  1347898 ms: Mark-sweep 1384.1 (1458.1) -> 1384.1 (1427.1) MB, 2659.4 / 0.0 ms  last resort GC in old space requested
[14628:000001C5D93EBC40]  1350475 ms: Mark-sweep 1384.1 (1427.1) -> 1384.1 (1427.1) MB, 2576.5 / 0.0 ms  last resort GC in old space requested


<--- JS stacktrace --->

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

Security context: 00000248B9D257C1 <JSObject>
    2: split(this=000000CF890516F9 <Very long string[12093]>)
    3: fn [C:\Users\jkalliau\AppData\Roaming\npm\node_modules\svgo\plugins\convertPathData.js:~56] [pc=000001C934FF3D35](this=00000175BEC37051 <Object map = 000000B31E6A17E1>,item=0000027C01EF5009 <JSObject>,params=00000175BEC37E89 <Object map = 000000B31E6BA439>)
    4: arguments adaptor frame: 3->2
    5: /* anonymous */(aka /* an...

FATAL ERROR: CALL_AND_RETRY_LAST Allocation failed - JavaScript heap out of memory
 1: node_module_register
 2: v8::internal::FatalProcessOutOfMemory
 3: v8::internal::FatalProcessOutOfMemory
 4: v8::internal::Factory::NewRawTwoByteString
 5: v8::internal::Smi::SmiPrint
 6: v8::internal::StackGuard::HandleInterrupts
 7: v8::internal::RegExpImpl::Exec
 8: v8::internal::RegExpImpl::Exec
 9: v8::internal::interpreter::BytecodeArrayRandomIterator::UpdateOffsetFromIndex
10: 000001C934E843C1
@JoKalliauer JoKalliauer changed the title FATAL ERROR out of memory after using 2.8GB RAM FATAL ERROR out of memory after using 2.8GB RAM (convertPathData, defaultoption) May 7, 2018
@hansottowirtz
Copy link

You can try replacing svgo with NODE_OPTIONS=--max_old_space_size=8192 node /usr/local/bin/svgo. I had to process a 120MB file which took 5GB of RAM.

@JoKalliauer
Copy link
Author

JoKalliauer commented Apr 19, 2019

@hansottowirtz
Thanks for letting me know.

But sadly i am using Windows 10.

cmd.exe NODE_OPTIONS=--max_old_space_size=8192 node C:/Users/jkalliau/AppData/Roaming/npm/svgo -i Input2.svg -o output2.svg
leads to (German)

Der Befehl "NODE_OPTIONS" ist entweder falsch geschrieben oder
konnte nicht gefunden werden.

which means (English)

The command "NODE_OPTIONS" is either misspelled or could not be found

cygwin: NODE_OPTIONS=--max_old_space_size=8192 node /cygdrive/c/Users/jkalliau/AppData/Roaming/npm/svgo -i Input2.svg -o output2.svg
leads to

module.js:549
    throw err;
    ^

Error: Cannot find module 'C:\cygdrive\c\Users\jkalliau\AppData\Roaming\npm\svgo'
    at Function.Module._resolveFilename (module.js:547:15)
    at Function.Module._load (module.js:474:25)
    at Function.Module.runMain (module.js:693:10)
    at startup (bootstrap_node.js:188:16)
    at bootstrap_node.js:609:3

cygwin: NODE_OPTIONS=--max_old_space_size=8192 node C:/Users/jkalliau/AppData/Roaming/npm/svgo -i Input2.svg -o output2.svg
leads to

C:\Users\jkalliau\AppData\Roaming\npm\svgo:2
basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')")
          ^^^^^^^

SyntaxError: missing ) after argument list
    at createScript (vm.js:80:10)
    at Object.runInThisContext (vm.js:139:10)
    at Module._compile (module.js:616:28)
    at Object.Module._extensions..js (module.js:663:10)
    at Module.load (module.js:565:32)
    at tryModuleLoad (module.js:505:12)
    at Function.Module._load (module.js:497:3)
    at Function.Module.runMain (module.js:693:10)
    at startup (bootstrap_node.js:188:16)
    at bootstrap_node.js:609:3

MINGW64:
leads to

bash: node: Kommando nicht gefunden.

(bash: node: commando not found)

@hansottowirtz
Copy link

For Windows you have to set an environment variable like this:
set ENV_VAR=value

So this could become:

set NODE_OPTIONS=--max_old_space_size=8192 && node C:/Users/jkalliau/AppData/Roaming/npm/svgo -i Input2.svg -o output2.svg

@JoKalliauer
Copy link
Author

@hansottowirtz
Thanks, but that still didn't solve my problem

in cmd.exe: set NODE_OPTIONS=--max_old_space_size=8192 && node C:/Users/jkalliau/AppData/Roaming/npm/svgo -i Input2.svg -o output2.svg

C:\Users\jkalliau\AppData\Roaming\npm\svgo:2
basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')")
          ^^^^^^^

SyntaxError: missing ) after argument list
    at createScript (vm.js:80:10)
    at Object.runInThisContext (vm.js:139:10)
    at Module._compile (module.js:616:28)
    at Object.Module._extensions..js (module.js:663:10)
    at Module.load (module.js:565:32)
    at tryModuleLoad (module.js:505:12)
    at Function.Module._load (module.js:497:3)
    at Function.Module.runMain (module.js:693:10)
    at startup (bootstrap_node.js:188:16)
    at bootstrap_node.js:609:3

I installed svgo from Cygwin, maybe I have to deinstall it and install it from cmd.exe

@pravinambekar
Copy link

pravinambekar commented Oct 15, 2019

Even

@hansottowirtz
Thanks, but that still didn't solve my problem

in cmd.exe: set NODE_OPTIONS=--max_old_space_size=8192 && node C:/Users/jkalliau/AppData/Roaming/npm/svgo -i Input2.svg -o output2.svg

C:\Users\jkalliau\AppData\Roaming\npm\svgo:2
basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')")
          ^^^^^^^

SyntaxError: missing ) after argument list
    at createScript (vm.js:80:10)
    at Object.runInThisContext (vm.js:139:10)
    at Module._compile (module.js:616:28)
    at Object.Module._extensions..js (module.js:663:10)
    at Module.load (module.js:565:32)
    at tryModuleLoad (module.js:505:12)
    at Function.Module._load (module.js:497:3)
    at Function.Module.runMain (module.js:693:10)
    at startup (bootstrap_node.js:188:16)
    at bootstrap_node.js:609:3

I installed svgo from Cygwin, maybe I have to deinstall it and install it from cmd.exe

Did you got this working ? , i have installed from node command prompt but it still does not work and throws error your mentioned above
In my case i have just 30mb svgo file which i am trying to optimize though command prompt command.. and it still throws " javascript heap out of memory" exception

@JoKalliauer
Copy link
Author

Did you got this working ? , i have installed from node command prompt but it still does not work and throws error your mentioned above

It still does not work on Windows, with the error-messages above

I tried on Ubuntu:

#!/bin/bash
wget https://upload.wikimedia.org/wikipedia/commons/archive/2/2e/20180507223736%21Germany_%28%2Bdistricts_%2Bmunicipalities%29_location_map_2013.svg -O input.svg
svgo -i input.svg -o output.svg

and I get:

#
# Fatal error in , line 0
# API fatal error handler returned after process out of memory
#

And the Comment from @hansottowirtz leads to

wget https://upload.wikimedia.org/wikipedia/commons/archive/2/2e/20180507223736%21Germany_%28%2Bdistricts_%2Bmunicipalities%29_location_map_2013.svg -O input.svg
NODE_OPTIONS=--max_old_space_size=8192
/usr/bin/svgo -i input.svg -o output2.svg

and results on Ubuntu in

<--- Last few GCs --->

[10799:0x2650db0]   580183 ms: Mark-sweep 1380.5 (1459.1) -> 1380.5 (1460.1) MB, 1004.1 / 0.0 ms  allocation failure GC in old space requested
[10799:0x2650db0]   581383 ms: Mark-sweep 1380.5 (1460.1) -> 1380.5 (1429.1) MB, 1199.7 / 0.0 ms  last resort GC in old space requested
[10799:0x2650db0]   582150 ms: Mark-sweep 1380.5 (1429.1) -> 1380.5 (1429.1) MB, 766.9 / 0.0 ms  last resort GC in old space requested


<--- JS stacktrace --->

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

Security context: 0x2aa043257c1 <JSObject>
    1: /* anonymous */(aka /* anonymous */) [/usr/lib/node_modules/svgo/plugins/convertPathData.js:~652] [pc=0x2dd33817bb47](this=0x1881e95822d1 <undefined>,item=0x249aafffbc71 <Object map = 0x2925d02feb11>,index=54)
    2: arguments adaptor frame: 3->2
    3: filter(this=0x3f02cb2de551 <JSArray[146]>)
    4: fn [/usr/lib/node_modules/svgo/plugins/convertPathData.js:~59] [pc=0x2dd33815a1f8](this=...

FATAL ERROR: CALL_AND_RETRY_LAST Allocation failed - JavaScript heap out of memory
 1: node::Abort() [node]
 2: 0x11e7fec [node]
 3: v8::Utils::ReportOOMFailure(char const*, bool) [node]
 4: v8::internal::V8::FatalProcessOutOfMemory(char const*, bool) [node]
 5: v8::internal::Factory::NewCode(v8::internal::CodeDesc const&, unsigned int, v8::internal::Handle<v8::internal::Object>, bool, int) [node]
 6: v8::internal::CodeGenerator::MakeCodeEpilogue(v8::internal::TurboAssembler*, v8::internal::EhFrameWriter*, v8::internal::CompilationInfo*, v8::internal::Handle<v8::internal::Object>) [node]
 7: v8::internal::compiler::CodeGenerator::FinalizeCode() [node]
 8: v8::internal::compiler::PipelineImpl::FinalizeCode() [node]
 9: v8::internal::compiler::PipelineCompilationJob::FinalizeJobImpl() [node]
10: v8::internal::Compiler::FinalizeCompilationJob(v8::internal::CompilationJob*) [node]
11: v8::internal::OptimizingCompileDispatcher::InstallOptimizedFunctions() [node]
12: v8::internal::StackGuard::HandleInterrupts() [node]
13: v8::internal::Runtime_StackGuard(int, v8::internal::Object**, v8::internal::Isolate*) [node]
14: 0x2dd337f842fd
Aborted (core dumped)

@e-tornike
Copy link

@JoKalliauer

I believe you need to set the environment variable for NODE_OPTIONS.

On Windows via:

set NODE_OPTIONS=--max_old_space_size=8192

On Linux via:

export NODE_OPTIONS=--max_old_space_size=8192

Alternatively, you can try svgcleaner. I found this reduces size more and is extremely fast, as it is written in Rust.

@sbenhai
Copy link

sbenhai commented Jan 13, 2021

Is there here any potential for for DoS attack?

@XhmikosR
Copy link
Contributor

I managed to make this compress on Windows with Node.js 14.15.5 and

C:\Users\xmr\Desktop>set NODE_OPTIONS=--max_old_space_size=8192 && svgo --pretty 1.svg -o 2.svg

1.svg:
Done in 172078 ms!
74491.22 KiB - 49.3% = 37762.557 KiB

That being said, maybe there are some improvements that can be made to reduce memory allocations?

@XhmikosR
Copy link
Contributor

XhmikosR commented Mar 9, 2021

@TrySound might be worth documenting the workaround for all OS'es in README for such special cases. The above will work on Windows.

I'm pretty sure we can improve the situation a bit later, but I'm not sure how much.

@XhmikosR
Copy link
Contributor

XhmikosR commented Mar 9, 2021

BTW @TrySound 2.1.0 vs 2.2.2 has a huge speed penalty, at least on my Windows VM:

C:\Users\xmr\Desktop>npm i svgo@~2.1 -g
C:\Users\xmr\AppData\Roaming\npm\svgo -> C:\Users\xmr\AppData\Roaming\npm\node_modules\svgo\bin\svgo
+ svgo@2.1.0
added 1 package from 1 contributor and updated 1 package in 1.848s

C:\Users\xmr\Desktop>set NODE_OPTIONS=--max_old_space_size=8192 && svgo 1.svg -o 2.svg

1.svg:
Done in 164252 ms!
74491.22 KiB - 49.3% = 37749.765 KiB

C:\Users\xmr\Desktop>npm i svgo@latest -g
C:\Users\xmr\AppData\Roaming\npm\svgo -> C:\Users\xmr\AppData\Roaming\npm\node_modules\svgo\bin\svgo
+ svgo@2.2.2
removed 1 package and updated 1 package in 1.521s

C:\Users\xmr\Desktop>set NODE_OPTIONS=--max_old_space_size=8192 && svgo 1.svg -o 2.svg

1.svg:
Done in 355186 ms!
74491.22 KiB - 49.3% = 37737.378 KiB

We really need a benchmark script. BTW the speed issue is noticeable with smaller files too, but it's not so huge.

https://github.com/svg/svgo/compare/v2.1.0...v2.2.2?w=1

Now, I'm not sure which commit is to blame yet. I could try to pinpoint it in the next days unless someone else beats me to it.

I suggest that you finish with the prettier stuff so that it doesn't pollute the git history anymore; it should have been made in one commit. And also add npm scripts to check and format.

@TrySound
Copy link
Member

TrySound commented Mar 9, 2021

Probably computing new styles. It does not cache anything yet.

@XhmikosR
Copy link
Contributor

XhmikosR commented Mar 9, 2021

I'll open a new issue for the performance regression.

@SethFalco
Copy link
Member

I'll close this issue as it's quite open-ended, and we're actively trying to improve the performance of SVGO as we go. I haven't personally been able to reproduce it under the same conditions, but appreciate that given a large enough SVG or low enough available memory this will still occur. My hope is that the situation here will improve over the next few releases.

Here are some stats showing how SVGO is performing with the main branch and other recent releases:

Version Time Reduction RAM Usage
main (8d6385b) 46585 ms 49.5% 2.827~ GB
v3.2.0 50651 ms 49.4% 2.856~ GB
v3.1.0 74173 ms 49.4% 3.166~ GB
v3.0.5 72965 ms 49.4% 3.225~ GB
v3.0.4 75558 ms 49.4% 3.187~ GB

Overall, time has significant improved, memory usage has marginally improved, and compression has negligibly improved.

The rationale for the time and memory improvements are mostly for #1918, and once merged will be used as the benchmark to ensure we understand the performance implications of new contributions.

Meanwhile, we may explore solutions like chunking large SVG files or clearing caches when we're using too much memory, etc. That would undermine speed ofc, but may improve stability if users are having OOM issues.

Rather than take action, since it's unclear when we've done enough, we'll just ensure all future work keeps memory/performance in mind, and that we profile SVGO and upstream dependencies to see where we can improve.

@JoKalliauer
Copy link
Author

JoKalliauer commented Mar 11, 2024

I retried it on another computer, and I can't reproduce the bug either. I consider it as fixed or not reproducable report. Thanks for your efford.


Edit: Others can still reproduce the bug.

@XhmikosR
Copy link
Contributor

I can certainly reproduce the issue:

C:\Users\xmr\Desktop>curl https://upload.wikimedia.org/wikipedia/commons/archive/2/2e/20180507223736%21Germany_%28%2Bdistricts_%2Bmunicipalities%29_location_map_2013.svg>input.svg
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100 72.7M    0 72.7M    0     0  5669k      0 --:--:--  0:00:13 --:--:-- 5544k

C:\Users\xmr\Desktop>npm i -g svgo

added 19 packages in 1s

9 packages are looking for funding
  run `npm fund` for details

C:\Users\xmr\Desktop>svgo -i input.svg -o output.svg

<--- Last few GCs --->

[1448:00000169B97559B0]     8658 ms: Scavenge (reduce) 2047.2 (2081.9) -> 2047.2 (2082.7) MB, 4.01 / 0.00 ms  (average mu = 0.169, current mu = 0.109) allocation failure;
[1448:00000169B97559B0]     8964 ms: Mark-Compact (reduce) 2048.1 (2082.7) -> 2048.1 (2083.7) MB, 230.03 / 0.00 ms  (+ 143.9 ms in 29 steps since start of marking, biggest step 5.4 ms, walltime since start of marking 389 ms) (average mu = 0.221, current m

<--- JS stacktrace --->

FATAL ERROR: Reached heap limit Allocation failed - JavaScript heap out of memory
----- Native stack trace -----

 1: 00007FF7025B71AB node::SetCppgcReference+16075
 2: 00007FF70252DCC6 v8::base::CPU::num_virtual_address_bits+79190
 3: 00007FF70252FED5 v8::base::CPU::num_virtual_address_bits+87909
 4: 00007FF702F9F061 v8::Isolate::ReportExternalAllocationLimitReached+65
 5: 00007FF702F887F8 v8::Function::Experimental_IsNopFunction+1336
 6: 00007FF702DEA120 v8::Platform::SystemClockTimeMillis+659328
 7: 00007FF702DE71A8 v8::Platform::SystemClockTimeMillis+647176
 8: 00007FF702DFC4BA v8::Platform::SystemClockTimeMillis+733978
 9: 00007FF702DFCD37 v8::Platform::SystemClockTimeMillis+736151
10: 00007FF702E0B62F v8::Platform::SystemClockTimeMillis+795791
11: 00007FF702ACBBE5 v8::CodeEvent::GetFunctionName+116773
12: 00007FF6A301AAFA

C:\Users\xmr\Desktop>node -v
v20.11.1

@KTibow
Copy link
Contributor

KTibow commented Mar 11, 2024

If you increase the old space size to 4000, it works fine.

➜  dir NODE_OPTIONS=--max_old_space_size=8192 pnpm exec svgo -i input.svg -o output.svg

input.svg:
Done in 67604 ms!
74491.22 KiB - 49.4% = 37659.443 KiB
➜  dir NODE_OPTIONS=--max_old_space_size=4000 pnpm exec svgo -i input.svg -o output.svg

input.svg:
Done in 106948 ms!
74491.22 KiB - 49.4% = 37659.443 KiB

I'm not sure if it's worth the time to try to decrease the amount of RAM used on giant files.

@XhmikosR
Copy link
Contributor

Yeah, I'm aware I just to make it clear that the issue does exist and it's not solved.

@SethFalco
Copy link
Member

SethFalco commented Mar 12, 2024

I can certainly reproduce the issue:

Thanks for sharing, I figured on some environments it'd still be possible.

I'm not sure if it's worth the time to try to decrease the amount of RAM used on giant files.

In my opinion, it is worth the time. It's not top priority, but making SVGO work with large files and be better equip to operate on smaller environments like phones or CI is favorable.

For example, I wouldn't want OhMySVG crashing on my phone (PinePhone/Linux) because SVGO is using too much memory. If we can find better ways to store and process data that reduces our memory footprint, it's just better for everyone.

Allocating memory takes time, which we're trying to get down, and reserving resources that other processes or the system memory cache could be using instead isn't considerate of our users or the other software installed on their machine.

TL;DR: Large files not being our primary use case, or the assumptions that clients have the resources to spare, isn't a good reason not to try to use resources more efficiently.


Edit: Sorry I'm less active right not btw, I'm sick. 😷

@SethFalco SethFalco removed their assignment Mar 12, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

9 participants