sdk icon indicating copy to clipboard operation
sdk copied to clipboard

How to set the maximum heap size in a self-contained executable?

Open gmpassos opened this issue 2 years ago • 17 comments

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.

gmpassos avatar Dec 08 '23 08:12 gmpassos

FYI: @kevmoo

gmpassos avatar Dec 08 '23 08:12 gmpassos

cc @rmacnak-google

bkonyi avatar Dec 08 '23 15:12 bkonyi

Any update? Regards.

gmpassos avatar Dec 19 '23 05:12 gmpassos

+1 Is there any updates? Thanks

fzyzcjy avatar Dec 24 '23 01:12 fzyzcjy

+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

rajmaniar avatar Jan 02 '24 23:01 rajmaniar

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.

gmpassos avatar Jan 14 '24 22:01 gmpassos

@a-siva ?

kevmoo avatar Jan 15 '24 22:01 kevmoo

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_size flag to gen_snapshot when 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.

bkonyi avatar Jan 15 '24 22:01 bkonyi

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)?

gmpassos avatar Jan 16 '24 07:01 gmpassos

@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 avatar Jan 16 '24 07:01 mraleph

@mraleph

Thanks for the advice.

I believe the AOT runtime approach will have the same performance as a self-executable.

gmpassos avatar Jan 16 '24 07:01 gmpassos

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.

mraleph avatar Jan 16 '24 08:01 mraleph

@bkonyi I don't think you need to pass that to gen_snapshot it 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.

bkonyi avatar Jan 16 '24 15:01 bkonyi

Maybe "DART_RUNTIME_OPTIONS", since not every Dart flavor has a VM.

gmpassos avatar Jan 16 '24 19:01 gmpassos

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.

bkonyi avatar Jan 17 '24 21:01 bkonyi

Any update?

gmpassos avatar Feb 07 '24 03:02 gmpassos

Any update?

https://dart-review.googlesource.com/c/sdk/+/346921 is being reviewed and should land soon,

a-siva avatar Feb 12 '24 19:02 a-siva

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.

bkonyi avatar Feb 22 '24 19:02 bkonyi

...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_OPTIONS
  • DART_SELF_EXEC_OPTIONS
  • DART_RUNTIME_OPTIONS 👍

Also, it should be documented what kinds of "options" can be passed through the ENV variable.

gmpassos avatar Feb 22 '24 20:02 gmpassos

...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_OPTIONS
  • DART_SELF_EXEC_OPTIONS
  • DART_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.

bkonyi avatar Feb 26 '24 22:02 bkonyi

FYI: https://github.com/dart-lang/sdk/issues/55767

gmpassos avatar May 18 '24 00:05 gmpassos