-
Notifications
You must be signed in to change notification settings - Fork 1.6k
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
[GR-46399] [GR-48232] [GR-48207] [GR-48180] Various important bug fixes for Native Image. #7277
Conversation
93d8885
to
9deec4a
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Some food for thought. I'm not sure this patch will be helping. Take with a grain of salt :-)
var containerMetrics = jdk.internal.platform.Container.metrics(); | ||
if (containerMetrics != null) { | ||
long memoryLimit = containerMetrics.getMemoryLimit(); | ||
if (memoryLimit >= 0) { | ||
/* | ||
* In containerized environments with a memory limit, do not use any headroom to | ||
* avoid OutOfMemoryErrors. | ||
*/ | ||
return (long) (memoryLimit * MAX_ALLOWED_CONTAINER_MEMORY_RATIO); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Aside: Note that this isn't really available memory in the container case. getAvailableMemorySizeLinux()
will return 80% of the set container memory limit. For awareness.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Right, I guess I shifted the meaning of available memory in this file from "available system memory" to "memory available to the builder". Maybe I should rename the methods...
/* | ||
* Based on total swap, set headroom somewhere between zero (no swap) and | ||
* MAX_HEADROOM_RATIO of available memory (total swap exceeds available memory). | ||
*/ | ||
long reasonableHeadroomKiB = (long) (Math.min(swapTotalKiB, memAvailableKiB) * MAX_HEADROOM_RATIO); | ||
return (memAvailableKiB + reasonableHeadroomKiB) * KiB_TO_BYTES; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I wonder what the headroom is supposed to achieve. It will likely not help systems with sufficient available memory (swap memory won't be used). I'd argue it will likely not help systems with very limited available memory, either. If this should help cases like GHA, where we'd have a virtualized system (or physical machine), not containers, where available memory - A
- will be small, this extra headroom will not help much. The generator will likely get about A * 1.2
of memory (instead of A
amount of memory prior this patch).
Considering a GHA runner with, say 8 GB of total RAM, it's not totally inconceivable with a maven build to only have say, 2GB
, available at an inconvenient time. Let that runner have 4GB of total swap, that particular runner will grant the native image generator 2.4 GB
of memory to use. Will that bump from 2 GB
to 2.4GB
really make a significant difference? I doubt it.
Considering a patch which used 50% of total swap space as the extra headroom, that would bump the memory to use for the image generator from 2
to 4 GB
, which doesn't seem to be too unreasonable. Some food for thought.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I wonder what the headroom is supposed to achieve.
It's supposed to compensate for the cases when available memory at startup is lower than it could be. Also, there's no easy way to determine swap space on macOS and Windows, so this helps there too.
Considering a patch which used 50% of total swap space as the extra headroom.
How about using 80% of free swap space, or 20% of available memory, whichever is larger? If we use 50% of total swap space but the swap if full, aren't we going to put the system in trouble?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I wonder what the headroom is supposed to achieve.
It's supposed to compensate for the cases when available memory at startup is lower than it could be.
Got it. It makes me think if the current patch will help (on Linux), though. I welcome the container simplification.
Considering a patch which used 50% of total swap space as the extra headroom.
How about using 80% of free swap space, or 20% of available memory, whichever is larger?
I think that would be better than the current approach.
If we use 50% of total swap space but the swap if full, aren't we going to put the system in trouble?
Note that the previous heuristic before considering available memory (only) - current master - didn't consider whether or not swap was available. It used 80% of physical memory, AFAIK. Considering a system with 64GB of memory and 32 gb of swap, it would use up to ~51gb of memory. On systems with little available memory at the time, it's conceivable that would cause swapping, possibly up to 100% of total swap. Now we are on the other extreme of the pendulum since only available memory (estimate before using swap) is being used. Given that, I find 50% of total swap isn't unreasonable as an upper bound to land somewhere between where we were and current master. That's my thinking.
Using the available swap metric has it's own set of problems as it's again a snapshot value at a specific point in time.
Anyway, I think the higher of '80% of free swap and 20% of available memory' will do the trick too.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Now we are on the other extreme of the pendulum since only available memory (estimate before using swap) is being used. Given that, I find 50% of total swap isn't unreasonable as an upper bound to land somewhere between where we were and current master. That's my thinking.
Yes, you are right and I agree. I'm just not sure if we want to go straight to the middle of the two approaches. My thinking was to try a 20% headroom first before going to 50% of swap.
Anyway, I think the higher of '80% of free swap and 20% of available memory' will do the trick too.
Ok, let's go with this for now. Keep in mind that we still make sure that the MaxRAMPercentage is about 100%, and that we use more than 32GB of memory to avoid compressed pointers. So we should be fine if the headroom exceeds any of the two upper limits.
9deec4a
to
dd8b035
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM. Thanks for taking my considerations into account.
Of course! Thanks for your feedback and taking the time to discuss different approaches. |
ea0f7c4
to
b218f21
Compare
b218f21
to
1b717f2
Compare
f10a363
to
3f7a965
Compare
@@ -1019,6 +1019,7 @@ def _native_image_launcher_extra_jvm_args(): | |||
] + svm_experimental_options([ | |||
'-H:IncludeResources=com/oracle/svm/driver/launcher/.*', | |||
'-H:-ParseRuntimeOptions', | |||
f'-R:MaxHeapSize={256 * 1024 * 1024}', |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Shouldn't this go into the bash launcher as well? My understanding is this would only affect the AOT compiled native-image
binary at runtime, right?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's correct, we don't have any good datapoints on how large this should be on HotSpot. Does Mandrel set a max heap already?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No, we don't set anything specifically.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The native driver uses the Serial GC which uses 80% of total memory as max heap by default, the HotSpot GC use a much smaller share. So unless we have a problem with bash launchers and a good understanding how much memory the driver needs on HotSpot, let's set a max heap for the native driver for now? (we'd notice memory leaks that way, too, unlikely they are HotSpot only)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sure.
This option is used, for example, by Native Build Tools to inject metadata generated with the agent or from the reachability metadata repository.
3f7a965
to
d28d39b
Compare
bac6f47
to
f664277
Compare
See oracle#7277 (comment) for motivation. We have been using this as the default in Mandrel since the 23.1 release.
No description provided.