-
Notifications
You must be signed in to change notification settings - Fork 0
T-03 JVM 메모리 상한을 컨테이너 한도 안으로 묶기 #55
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
Merged
+7
−2
Merged
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
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.
🩺 Stability & Availability | 🟠 Major | 🏗️ Heavy lift
🧩 Analysis chain
🏁 Script executed:
Repository: BCSDLab/BCSD_INTERNAL_API_V2
Length of output: 245
🏁 Script executed:
Repository: BCSDLab/BCSD_INTERNAL_API_V2
Length of output: 1284
🌐 Web query:
Java 21 java launcher MaxRAMPercentage MaxMetaspaceSize ReservedCodeCacheSize MaxDirectMemorySize container memory semantics SerialGC nproc ergonomics💡 Result:
Java 21, like recent long-term support releases, is natively container-aware, meaning the JVM automatically detects cgroup memory and CPU limits to configure its internal resources [1][2]. Memory Semantics and Sizing The JVM interprets container memory limits to define various memory pools. Rather than hard-coding heap sizes with -Xmx, which is discouraged in containerized environments [3], it is best practice to use percentage-based flags [2][4]: -XX:MaxRAMPercentage: Sets the maximum heap size as a percentage of the container's memory limit (default is typically 25% if no explicit heap size is set, but often tuned to 70-80% in production) [5][1][3]. -XX:MaxMetaspaceSize: Constrains metaspace growth. By default, metaspace is unbounded, which can lead to container OOM kills; setting an explicit limit (e.g., 256m or 512m) is recommended [6][1][3]. -XX:ReservedCodeCacheSize: Defaults to 240 MB. For large applications with many classes, increasing this (e.g., 512 MB) prevents performance degradation or startup failures [6][3]. -XX:MaxDirectMemorySize: Governs memory allocated outside the heap (e.g., for NIO buffers). It defaults to approximately the maximum heap size if not explicitly set [6][7]. Container memory overhead is significant. A rule of thumb is that the container memory limit should be higher than the sum of JVM memory pools to account for thread stacks, metaspace, direct memory, and native overhead [1]. Common advice is to add 25-50% headroom over the sum of your configured JVM pool limits [1]. GC Ergonomics and CPU Detection The JVM uses "ergonomics" to select the garbage collector (GC) based on detected resources [8]. - Default GC Selection: In environments with fewer than 2 CPUs and less than 1792 MB of RAM, the JVM traditionally defaults to SerialGC [9][10][11]. On "server-class" machines (2+ CPUs, 1792 MB+ RAM), it typically defaults to G1GC [9][10][11]. - CPU Awareness: The JVM uses the number of CPUs allocated to the container (cgroup limits) for thread pool sizing (e.g., GC threads, ForkJoinPool) [2][4]. While there were known issues in older Java 21 versions reporting host CPU counts, these have been addressed in later 21.x releases [12]. - Tuning: If the JVM selects SerialGC but you require lower pause times, you should explicitly set the GC (e.g., -XX:+UseG1GC or -XX:+UseZGC) [9][10]. You can also override CPU detection using -XX:ActiveProcessorCount if the container environment provides incorrect metrics to the JVM [4]. General Advice - Use -XX:+UseContainerSupport (enabled by default in modern OpenJDK) [3][2]. - Use -Xlog:os+container=trace to debug how the JVM perceives container limits [12]. - Monitor with Native Memory Tracking (-XX:NativeMemoryTracking=summary) to understand actual native memory usage beyond the heap [6].
Citations:
🌐 Web query:
site:docs.oracle.com/en/java/javase/21/docs/specs/man/java.html MaxMetaspaceSize ReservedCodeCacheSize MaxDirectMemorySize MaxRAMPercentage💡 Result:
The flags MaxMetaspaceSize, ReservedCodeCacheSize, MaxDirectMemorySize, and MaxRAMPercentage are JVM options used to configure memory limits for different non-heap memory areas and overall resource management [1]. MaxMetaspaceSize: This option sets the maximum amount of native memory that can be used for class metadata [1]. If not set, the metaspace size is limited only by the available native memory of the host system. ReservedCodeCacheSize: This option specifies the maximum size of the code cache, which stores compiled native code produced by the Just-In-Time (JIT) compiler [1]. The default value is platform-dependent. MaxDirectMemorySize: This option limits the total size of direct buffer allocations (NIO direct memory) [1]. If this flag is not specified, the JVM chooses the size for NIO direct-buffer allocations automatically [1]. MaxRAMPercentage: This option defines the maximum amount of memory the JVM heap can occupy, expressed as a percentage of the total available physical RAM [1]. This is particularly useful in containerized environments to ensure the JVM scales its heap according to the container's memory limits, typically accepting a value between 0 and 1 (e.g., 0.25 for 25%) [1]. For these flags, memory sizes are typically specified in bytes, with scaling suffixes such as k/K (kilobytes), m/M (megabytes), or g/G (gigabytes) [1]. For example, setting the direct memory limit to 1 megabyte can be done as: -XX:MaxDirectMemorySize=1m [1]
Citations:
🌐 Web query:
site:docs.oracle.com/en/java/javase/21/docs/specs/man/java.html ExitOnOutOfMemoryError container cgroup OOM kill💡 Result:
The ExitOnOutOfMemoryError flag and container cgroup OOM kills are independent mechanisms [1]. ExitOnOutOfMemoryError is a JVM-specific flag that triggers a JVM termination only when the JVM encounters a java.lang.OutOfMemoryError exception during its internal operations (such as heap allocation failures) [1]. In contrast, a cgroup OOM (Out of Memory) kill is an external event initiated by the Linux kernel when a container exceeds its configured memory limit. Because this action is performed by the host kernel at the operating system level, the JVM is unaware of the event and does not process it as a java.lang.OutOfMemoryError [1]. Consequently, the ExitOnOutOfMemoryError flag will not trigger in response to a cgroup OOM kill; the container process is simply terminated by the kernel [1].
Citations:
Keep JVM memory maxima below the 256 MiB cgroup limit.
If the runtime limit is 256 MiB, the heap, metaspace, and direct-memory maxima already total about 259.2 MiB.
ReservedCodeCacheSize=64mand other native allocations add further pressure. Reduce these limits or raise the cgroup limit, then validate peak RSS.ExitOnOutOfMemoryErrorcannot prevent a cgroup OOM kill.🤖 Prompt for AI Agents