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

doc: clarify default heap size formula since node 12 #39107

Open
1 task
naseemkullah opened this issue Jun 21, 2021 · 12 comments
Open
1 task

doc: clarify default heap size formula since node 12 #39107

naseemkullah opened this issue Jun 21, 2021 · 12 comments
Labels
doc Issues and PRs related to the documentations. v8 engine Issues and PRs related to the V8 dependency.

Comments

@naseemkullah
Copy link

📗 API Reference Docs Problem

  • Version:12+

  • Platform: all

  • Subsystem: n/a

Location

Section of the site where the content exists

Affected URL(s):

Description

Concise explanation of the problem

Despite the explanation here : #25576 (comment)

I am not clear on the value of heap size for my instance. Given a formula/calculator, a user can then know for sure the default value based on the GB of memory available. It would be great to have this in the docs.


  • I would like to work on this issue and
    submit a pull request.
@naseemkullah naseemkullah added the doc Issues and PRs related to the documentations. label Jun 21, 2021
@ghost
Copy link

ghost commented Jun 22, 2021

I wanna work on it please assigned it to me

@naseemkullah
Copy link
Author

Hey @gtp-m3 I am not a maintainer of node and so cannot assign you. Hopefully one will see this and assign you to it! Thanks.

@Ayase-252
Copy link
Member

@gtp-m3

Thanks for your help. It is yours.

BTW, you can work on any issue without prior assignment. Good luck.

@ghost
Copy link

ghost commented Jun 23, 2021

@Ayase-252 ok thanks

@ghost
Copy link

ghost commented Jun 23, 2021

@naseemkullah can you explain what should I add to doc

@ghost
Copy link

ghost commented Jun 23, 2021

@Ayase-252 @naseemkullah should i add a calculator who will show memory consumption for different machine

@Ayase-252
Copy link
Member

Should a paragraph to mention the default heap size be sufficient? IMO, a calculator seems too "heavy" to maintain.

@naseemkullah
Copy link
Author

Yes just a sentence as to how it's calculated exactly. Maybe with 2 or 3 examples with different available memory for clarity

@targos
Copy link
Member

targos commented Jun 23, 2021

References:

size_t Heap::HeapSizeFromPhysicalMemory(uint64_t physical_memory) {
// Compute the old generation size and cap it.
uint64_t old_generation = physical_memory /
kPhysicalMemoryToOldGenerationRatio *
kHeapLimitMultiplier;
old_generation =
std::min(old_generation,
static_cast<uint64_t>(MaxOldGenerationSize(physical_memory)));
old_generation =
std::max({old_generation, static_cast<uint64_t>(V8HeapTrait::kMinSize)});
old_generation = RoundUp(old_generation, Page::kPageSize);
size_t young_generation = YoungGenerationSizeFromOldGenerationSize(
static_cast<size_t>(old_generation));
return static_cast<size_t>(old_generation) + young_generation;
}

TEST(Heap, HeapSizeFromPhysicalMemory) {
const size_t MB = static_cast<size_t>(i::MB);
const size_t pm = i::Heap::kPointerMultiplier;
const size_t hlm = i::Heap::kHeapLimitMultiplier;
// The expected value is old_generation_size + 3 * semi_space_size.
ASSERT_EQ(128 * hlm * MB + 3 * 512 * pm * KB,
i::Heap::HeapSizeFromPhysicalMemory(0u));
ASSERT_EQ(128 * hlm * MB + 3 * 512 * pm * KB,
i::Heap::HeapSizeFromPhysicalMemory(512u * MB));
ASSERT_EQ(256 * hlm * MB + 3 * 2048 * pm * KB,
i::Heap::HeapSizeFromPhysicalMemory(1024u * MB));
ASSERT_EQ(512 * hlm * MB + 3 * 4096 * pm * KB,
i::Heap::HeapSizeFromPhysicalMemory(2048u * MB));
ASSERT_EQ(
1024 * hlm * MB + 3 * 8192 * pm * KB,
i::Heap::HeapSizeFromPhysicalMemory(static_cast<uint64_t>(4096u) * MB));
ASSERT_EQ(
1024 * hlm * MB + 3 * 8192 * pm * KB,
i::Heap::HeapSizeFromPhysicalMemory(static_cast<uint64_t>(8192u) * MB));
}

@targos targos added the v8 engine Issues and PRs related to the V8 dependency. label Aug 9, 2021
@jasikpark
Copy link

Is this pertinent?:

size_t Heap::MaxOldGenerationSize(uint64_t physical_memory) {
size_t max_size = V8HeapTrait::kMaxSize;
// Finch experiment: Increase the heap size from 2GB to 4GB for 64-bit
// systems with physical memory bigger than 16GB. The physical memory
// is rounded up to GB.
constexpr bool x64_bit = Heap::kHeapLimitMultiplier >= 2;
if (FLAG_huge_max_old_generation_size && x64_bit &&
(physical_memory + 512 * MB) / GB >= 16) {
DCHECK_EQ(max_size / GB, 2);
max_size *= 2;
}
return std::min(max_size, AllocatorLimitOnMaxOldGenerationSize());
}

I'm currently trying to sort out what the max possible setting is + at what breakpoints does node choose which settings?

I want to max out my performance for a CI run :)

@SomaSharath
Copy link

Hey @naseemkullah @targos @Ayase-252

Any idea, if someone is working on this? It'd be nice if this can be clarified please

@johanarnor
Copy link

I found this issue after digging around what happens if you don't specify --max-old-space-size. And since the code linked above is a bit hard for me to understand, I simply ran some tests with docker.

I spun up a container with docker run -it node:18 node and changed the memory limit in Docker Desktop between the runs.

I got the heap size with Math.round(require('v8').getHeapStatistics().total_available_size / (1024 * 1024)).
I also double checked the total memory amount with Math.round(require("os").totalmem() / 1024 / 1024) in parenthesis.

Docker memory totalmem() heap size
1 GB 915 MB 466 MB
2 GB 1919 MB 980 MB
4 GB 3928 MB 2007 MB
6 GB 5934 MB 2092 MB
8 GB 7946 MB 2091 MB
12 GB 11958 MB 2092 MB
15.5 GB 15479 MB 2091 MB
16 GB 15982 MB 4140 MB

So the behaviour is a bit weird between after 4 GB I would say. The 2 GB limit is a bit low, especially for servers with just below 16 GB of RAM (like Heroku's performance-l dyno with 14 GB of RAM). And the jump at 16 GB is also strange. I don't have easy access to a computer with more than 16 GB of RAM, but I suspect it will stay at 4 GB looking at the code above.

I also ran docker run -it node:18 node --max-old-space-size=5120 to verify the heap size and I got 5164 MB in that case.

I'm probably not the one to document this, but I wanted to share it regardless if anyone finds it useful!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
doc Issues and PRs related to the documentations. v8 engine Issues and PRs related to the V8 dependency.
Projects
None yet
Development

No branches or pull requests

6 participants