sdk
sdk copied to clipboard
How to set the maximum heap size in a self-contained executable?
The Dart VM currently accepts the parameter --old_gen_heap_size=%MB to define the maximum size of the old gen heap size (in MB).
When compiling a Dart "script" to a self-contained executable (dart compile exe foo.dart), it comes with a Dart runtime that also has a GC.
Is it possible to define the maximum size of the heap for a self-contained executable?
I couldn't find any way to do it.
Actually, it's crucial to inform the GC of the maximum heap size. I believe this parameter should be a default setting, not an "experimental" one.
The lack of the ability to set the heap limit may lead to incorrect behavior, as the software might attempt to allocate more memory than necessary. This becomes particularly critical when reserving memory for other processes or managing servers with limited resources. Configuring this tuning enables running the GC appropriately in various contexts.
It's important to note that attempting to allocate excessive memory in a restricted environment can potentially "crash" a server or container.
FYI: @kevmoo
cc @rmacnak-google
Any update? Regards.
+1 Is there any updates? Thanks
+1 -- this is a pretty critical config to expose
Also, holy wow, this is horrific logic to use to set the default: https://github.com/dart-lang/sdk/blob/main/runtime/vm/globals.h#L61
FYI: @kevmoo @mit-mit
To provide context: this is hindering some deployments, as we can't share the same server with multiple containers. We need to use different smaller servers to avoid this issue.
@a-siva ?
I can look into picking this up sometime this week. I'm not 100% sure, but I don't think this should be too difficult to get wired up. @a-siva, @rmacnak-google, or @alexmarkov will know for sure, but I think we need to do two things:
- Pass the
--old_gen_heap_sizeflag togen_snapshotwhen compiling the initial AOT snapshot - Configure the generated executable binary to pass the same flag to the embedded
dartaotruntime
The first part is simple, the second part might be more tricky.
Some important decisions need clarification:
-
Will the maximum heap size be fixed in the binary?
-
Can it be overwritten with an environment variable (or something similar)?
@bkonyi I don't think you need to pass that to gen_snapshot it does not really care about heap size limits. I would suggest just making it so that we read contents of DART_VM_OPTIONS (or similarly named environment variable) and pass them as VM flags. We can probably make it default VM feature - so that all variations of dart respect that environment variable.
@gmpassos Instead of using dart compile exe you can switch to using dart compile aot-snapshot and running resulting binary through dartaotruntime. Then you should be able to pass VM options:
$ dart compile aot-snapshot -o a.aot a.dart
$ dartaotruntime --old_gen_heap_size=... a.aot
It has other benefits (e.g. you can actually profile your application with something like perf and symbols will resolve correctly) compared to using the output of compile exe
@mraleph
Thanks for the advice.
I believe the AOT runtime approach will have the same performance as a self-executable.
I believe the AOT runtime approach will have the same performance as a self-executable.
It will. The output of exe is just an AOT snapshot and dartaotruntime glued together. There aren't any performance differences between the two.
@bkonyi I don't think you need to pass that to
gen_snapshotit does not really care about heap size limits.
Ah, I thought one of the issues with passing this flag was that the snapshot needed to be generated with the same flags. Now that I'm writing this, I'm probably confusing this with generating AppJIT snapshots.
I would suggest just making it so that we read contents of DART_VM_OPTIONS (or similarly named environment variable) and pass them as VM flags. We can probably make it default VM feature - so that all variations of dart respect that environment variable.
That seems like a less complicated approach. I'll go ahead and do that.
Maybe "DART_RUNTIME_OPTIONS", since not every Dart flavor has a VM.
I have a WIP CL that adds support for providing VM options via DART_VM_OPTIONS. I'll hopefully be able to send it out for review sometime tomorrow.
Any update?
Any update?
https://dart-review.googlesource.com/c/sdk/+/346921 is being reviewed and should land soon,
I've abandoned the original CL in favor of https://dart-review.googlesource.com/c/sdk/+/353820, which will only work for self-contained executables generated with dart compile exe.
...which will only work for self-contained executables generated with
dart compile exe.
I agree that a solution specific to self-executables is better and avoids any regression issues.
If it's only for self-executables, should the ENV variable name DART_VM_OPTIONS retain the VM designation? Perhaps something more specific to the platform could be clearer and less misleading:
DART_NATIVE_OPTIONS👍DART_EXE_OPTIONSDART_SELF_EXEC_OPTIONSDART_RUNTIME_OPTIONS👍
Also, it should be documented what kinds of "options" can be passed through the ENV variable.
...which will only work for self-contained executables generated with
dart compile exe.I agree that a solution specific to self-executables is better and avoids any regression issues.
If it's only for self-executables, should the ENV variable name
DART_VM_OPTIONSretain theVMdesignation? Perhaps something more specific to the platform could be clearer and less misleading:
DART_NATIVE_OPTIONS👍DART_EXE_OPTIONSDART_SELF_EXEC_OPTIONSDART_RUNTIME_OPTIONS👍Also, it should be documented what kinds of "options" can be passed through the ENV variable.
We're just going to stick with DART_VM_OPTIONS for now, but we can always revisit this in the future.
It's hard to document what options can be passed through this variable since, in theory, it could be any of the options listed under dart --help --verbose. None of the verbose flags are officially supported and could be changed or removed at any point.
FYI: https://github.com/dart-lang/sdk/issues/55767