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

worker: add flag to control old space size #43995

Open
wants to merge 3 commits into
base: main
Choose a base branch
from

Conversation

kvakil
Copy link
Contributor

@kvakil kvakil commented Jul 26, 2022

This adds a new flag --thread-max-old-space-size (name completely
provisional). This flag lets the user configure the size of the main
thread's
old space size. This has two advantages over the existing
--max-old-space-size flag:

  1. It allows setting the old space size for the main thread and using
    resourceLimits for worker threads. Currently resourceLimits will
    be ignored when --max-old-space-size is set (see the attached
    issues).
  2. It is implemented using V8's public API, rather than relying on V8's
    internal flags whose stability and functionality are not guaranteed.

The downside is that there are now two flags which (in most cases) do
the same thing, so it may cause some confusion. I also think that we
should deprecate --max-old-space-size, since the semantics feel pretty
error-prone, but that's a story for another day.

Refs: #41066
Refs: #43991
Refs: #43992

@nodejs-github-bot nodejs-github-bot added c++ Issues and PRs that require attention from people who are familiar with C++. lib / src Issues and PRs related to general changes in the lib or src directory. needs-ci PRs that need a full CI run. labels Jul 26, 2022
@kvakil kvakil force-pushed the worker-flag branch 2 times, most recently from c633fdb to a08fc49 Compare July 26, 2022 05:15
This adds a new flag `--thread-max-old-space-size` (name completely
provisional). This has two advantages over the existing
`--max-old-space-size` flag:

1. It allows setting the old space size for the main thread and using
   `resourceLimits` for worker threads. Currently `resourceLimits` will
   be ignored when `--max-old-space-size` is set (see the attached
   issues).
2. It is implemented using V8's public API, rather than relying on V8's
   internal flags whose stability and functionality are not guaranteed.

The downside is that there are now two flags which (in most cases) do
the same thing, so it may cause some confusion. I also think that we
should deprecate `--max-old-space-size`, since the semantics feel pretty
error-prone, but that's a story for another day.

Refs: nodejs#41066
Refs: nodejs#43991
Refs: nodejs#43992
@tniessen
Copy link
Member

I think we should strive for a uniform approach across all worker limits here.

IIRC from #43630, the stack size is also vastly inconsistent: the main thread has a reserved stack size (which is usually around 8 MiB, except on Windows, which is what #43630 is about), and then a small part of that is used as the V8 stack size of the main application thread (less than 1 MiB). Worker threads, however, do not seem to inherit either, and the 4 MiB default limit seems to be the reserved stack size of the thread and also the V8 stack size of the worker thread.

@kvakil
Copy link
Contributor Author

kvakil commented Jul 27, 2022

IIRC from #43630, the stack size is also vastly inconsistent: the main thread has a reserved stack size (which is usually around 8 MiB, except on Windows, which is what #43630 is about), and then a small part of that is used as the V8 stack size of the main application thread (less than 1 MiB). Worker threads, however, do not seem to inherit either, and the 4 MiB default limit seems to be the reserved stack size of the thread and also the V8 stack size of the worker thread.

I did not know that about stack_size, thanks for sharing. I see in the code we do default to 4MB, and we use that as the stack size.

I think we should strive for a uniform approach across all worker limits here.

Could you elaborate more on this? What does a "uniform approach" entail? Are you just suggesting we add the other three relevant flags, or something else?

@tniessen
Copy link
Member

Could you elaborate more on this? What does a "uniform approach" entail?

What I mean is: the mechanism through which resource limits for workers are determined should be the same for all resource limits (unless there is a good reason to have different mechanisms).

Are you just suggesting we add the other three relevant flags, or something else?

I am not sure if adding command line flags is the right approach at all.


I believe @addaleax might have more insight here.

@addaleax
Copy link
Member

Not sure what I can add to the conversation here – I would definitely shy away from adding command line flags (process-level config) for controlling worker thread behavior (thread-level config).

Regarding the stack size, I don’t remember all the original context but stack size limits for threads definitely vary quite a bit, and iirc some platforms had significantly lower stack limits for spawned threads than for the main thread, making it difficult to use Worker threads there (and to tell V8 about the correct stack size, which is just as relevant).

@kvakil
Copy link
Contributor Author

kvakil commented Jul 27, 2022

Sorry, I think there's some confusion because I poorly named the flag here. What I'm proposing (& what this diff adds) is essentially --main-thread-max-old-space-size (i.e. setting the max old space size of the main thread). Currently we only have --max-old-space-size which is a process-level flag which sets the max old space size for all created worker threads and can't be overridden by resourceLimits -- cf. the referenced issues.

@addaleax
Copy link
Member

Ah yeah – the option should be named and described differently then, I would say :)

@kvakil
Copy link
Contributor Author

kvakil commented Jul 28, 2022

I will try to come up with a better name (so far I am leaning towards something like --main-thread-max-old-space-size, but that's very verbose). Feel free to suggest ideas!

Hopefully with my clarification the need for some sort of further knob is pretty clear: setting the max old space size today means overriding all resourceLimits.

I think there's still a question of how exactly the new flag should interact with resourceLimits. There are a couple of reasonable ideas:

  1. Doesn't interact: new flag sets only the max old space size of the main thread. For worker threads, if resourceLimits.maxOldSpaceSizeMb is not set, then the existing behavior remains (choose a reasonable default based on the system memory). That is what this diff currently implements.

  2. Defaults: new flag sets the max old space size of the main thread and sets the default value for the max old space size of worker threads when resourceLimits.maxOldSpaceSizeMb is not set. Users can set a higher or lower resourceLimits if desired.

  3. Defaults & limits: new flag sets the max old space size of the main thread and sets the default & maximum value for resourceLimits.maxOldSpaceSizeMb. Trying to use a higher value of resourceLimits.maxOldSpaceSizeMb won't be respected; the value of the flag is used instead. I think this is what @bnoordhuis is suggesting in worker: resourceLimits overridden by --max-old-space-size #43991 (comment).

My inclination is to proceed with (1), because both (2) and (3) can be implemented by the user anyway.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
c++ Issues and PRs that require attention from people who are familiar with C++. lib / src Issues and PRs related to general changes in the lib or src directory. needs-ci PRs that need a full CI run.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants