ibmruntimes / Semeru-Runtimes

Issue repo for all things IBM Semeru Runtimes
14 stars 3 forks source link

Calculation of maximum new space size #81

Open Edwin-192 opened 2 months ago

Edwin-192 commented 2 months ago

We are currently configuring our docker container with the JVM flags '-XX:InitialRAMPercentage=40.0' and '-XX:MaxRAMPercentage=80.0'. The container has a size of 750mb, which should result in an Xms of 450M and Xmx of 600mb.

In our reported micrometer metrics we however noted that the combined (tenure+nursery) jvm_memory_max metrics for the heap area are more than 600mb.

Looking into the container, I got the settings below: Jvm max memory calculation

In this image you can see that the Xms and Xms are calculated correctly according to the percentages. The Xmns and Xmox combined are however more than 600mb. This is not what I would expect.

After noticing this, I experimented by setting the initial and max ram percentage both to 80% (which we prefer not to do). This resulted in the Xmns and Xmnx to be the same value, and the Xmnx + Xmox == Xmx, which leads me to believe that the calculation of the Xmnx or Xmox somehow is incorrect when the InitialRAMPercentage and MaxRAMPercentage are not the same value.

In case this is intended behavior, could someone explain why it is calculated this way?

Update: For extra information, we are running on ibm-semeru-runtimes:open-17.0.10_7-jre-jammy

pshipton commented 2 months ago

@dmitripivkine @amicic pls take a look.

dmitripivkine commented 2 months ago

This is calculation mistake most likely related to usage of -XX:MaxRAMPercentage. I am going to look. Meanwhile I believe explicit usage of -Xmx and -Xms can be a workaround. It would not provide you flexibility with various container sizes obviously.

dmitripivkine commented 2 months ago

ok, I see how we got this value, this is intentional (regardless is it correct or not, this is another question): Xmox is set as (Xmx - Xmns) = 600 * 1024 - 115200 = 499200

dmitripivkine commented 2 months ago

So, an intention in the code is to assume than Nursery can stay in it's initial size and Tenure can be expanded to use the rest of the heap. Total usage of heap memory should not exceed -Xmx value at any conditions.

amicic commented 2 months ago

Evertyhing is ok here. The fact that Xmox + Xmnx > Xmx does not mean that at any given point of time current Tenure size + current Nursery size will be larger than Xmx value. Current Tenure size can float anywhere between between Xmos and (Xmx - current Nursery size), but since Nursery minimum size is Xmns, then the maximum Tenure is Xmox = Xmx - Xmns.

Edwin9292 commented 2 months ago

So in the example of my screenshot, what would happen if the nursery grows to 145M (which fits within the Xmnx, but is more than Xmns) and the Tenure grows to 480M (which is less than Xmx - Xmns).

Would i get an OOM in that case, because the nursery + tenure > Xmx, or wouldn't I, since both the nursery and tenure are within their own limits?

(posting from a different account, don't have access to my work account at the moment)

amicic commented 2 months ago

Since Tenure size can float anywhere between Xmos and (Xmx - current Nursery size), and since in your example current Nursery size is 145M and Xmx is 600M, Tenure can grow up to max of 600M - 145M = 455M. It can't grow at that moment to 480M.

If in future, Nursery contracts to a smaller value, say 100M, Tenure can after that continue to grow up to 500M.

Tenure and Nursery have their own independent limits (up to Xmox and Xmnx respectively), but also at any given point of time obey an additional limit of their sum being no larger than Xmx.

Edwin9292 commented 2 months ago

I see, in your previous post you mentioned Xmx - Xmns, but if its Xmx - current nursery size it makes more sense to me.

Could this information maybe also be added to the docs?

The Xmo docs for example mentions that the Xmox equals Xmx, which appearently is not the case. Also, both the Xmn and Xmo docs mention nothing about possibly going OOM before their max is reached, if the nursery + tenury combined are above Xmx.

Either way, thank you for clarifying this behavior.

dmitripivkine commented 2 months ago

Just to clarify: You are not going to get OOM until entire heap to be exhausted. GC keeps balance between Tenure and Nursery automatically.

dmitripivkine commented 2 months ago

Also Tenure + Nursery combined can not be larger than max heap size.

amicic commented 2 months ago

I see, in your previous post you mentioned Xmx - Xmns, but if its Xmx - current nursery size it makes more sense to me.

Both are correct, Xmx - current nursery size is the upper limit for a given moment, but Xmx - Xmns is also an absolute limit since current Nursery size cannot go below Xmns. When JVM starts it can really report the absolute limit.

The Xmo docs for example mentions that the Xmox equals Xmx, which appearently is not the case.

You refer to this:

image

Indeed, seems incorrect, it should state that Xmox defaults to Xmx - Xmns.

Also, both the Xmn and Xmo docs mention nothing about possibly going OOM before their max is reached, if the nursery + tenury combined are above Xmx.

OOM will not occur because Nursery + Tenure is above Xmx. Nursery + Tenure jsut can't ever be above Xmx. They will stop growing at the point their sum is equal to Xmx. But it does not mean that application cannot allocate (so to cause OOM) at that point. OOM will occur if there is no free space after a GC, so that an allocation attempt cannot be satisfied. The total current heap size does not tell anything about how much live date (or free memory is) at the point of time.

amicic commented 2 months ago

Raised this issue to fix that Xmox default value: https://github.com/eclipse-openj9/openj9-docs/issues/1363

dmitripivkine commented 1 month ago

Documentation has been fixed. @pshipton This item can be closed.