Automatic Memory Profile System
Apinizer uses an automatic memory profile system at container startup across all modules (Worker, Cache, Manager, Integration). This system:- Detects the memory allocated to the container via cgroup
- Selects an appropriate profile based on the memory amount
- Automatically determines the GC algorithm and heap percentage within the profile
Profile Selection Table
The profile selection is printed to pod logs at container startup. Example:
Profile Selection Priority
The system decides in the following order:JVM_MEMORY_PROFILEenvironment variable — If set (low,medium, orhigh), this profile is used directly- GC/heap settings in
JAVA_OPTS— If the user specifies a GC (-XX:+UseG1GC, etc.) or heap (-XX:MaxRAMPercentage,-Xmx, etc.) inJAVA_OPTS, the automatic values are overridden - Automatic detection — If none of the above are present, container memory is read from cgroup and the profile is selected according to the table
Garbage Collector Types
Since Apinizer uses Eclipse Temurin 25 as its base image, the following GC algorithms are supported:Serial GC
The simplest, single-threaded GC algorithm. Does not create additional thread and memory overhead for small heap sizes.- When to use: ≤ 768 MB memory, low-traffic environments, test/development
- Advantage: Minimum CPU and memory overhead
- Disadvantage: Application completely stops during GC (Stop-the-World)
- JVM parameter:
-XX:+UseSerialGC
G1GC (Garbage-First)
A region-based GC that can work in parallel and concurrently. Divides the heap into equal regions, making garbage collection time predictable.- When to use: 769 MB – 1536 MB memory, medium-traffic environments
- Advantage: Balanced throughput and low GC pause
- Disadvantage: Uses more CPU compared to Serial GC
- JVM parameters:
-XX:+UseG1GC -XX:G1HeapRegionSize=1m
ZGC (Z Garbage Collector)
A low-latency, scalable GC. GC pauses are typically under 1 ms regardless of heap size.- When to use: > 1536 MB memory, high-traffic production environments
- Advantage: Constant and very low GC pause (sub-millisecond), excellent performance with large heaps
- Disadvantage: Consumes more native memory due to colored pointers and multi-mapping (~15-20% overhead)
- JVM parameters:
-XX:+UseZGC -XX:+AlwaysPreTouch
Comparison Table
ZGC Safety Cap
Problem
ZGC consumes significantly more native memory (off-heap memory) compared to other GCs due to colored pointer and multi-mapping mechanisms. When upgrading from existing installations, the oldMaxRAMPercentage=80.0 setting, while safe for G1GC, can cause container OOM Kill with ZGC.
Automatic Cap Mechanism
Apinizer implements a safety mechanism to prevent this:- When ZGC is automatically selected and the user has set
MaxRAMPercentageabove 70% inJAVA_OPTS:- The heap percentage is automatically capped at 70%
- The following warning message appears in pod logs:
Disabling the Cap
To disable the cap mechanism, explicitly specify the GC inJAVA_OPTS. This disables both automatic GC selection and the safety cap:
Module-Specific Recommendations
Worker (Gateway)
Gateway pods handle high-concurrency HTTP traffic. Memory configuration is determined by traffic intensity. Low traffic (≤ 500 TPS):Cache (Hazelcast)
Cache Server pods hold large data structures and have long-lived objects. ZGC’s low GC pause at large heap sizes reduces the risk of timeouts in Hazelcast cluster communication. Standard cache usage:Manager
Manager pods provide the web interface and configuration management. They do not process heavy traffic; the standard automatic profile is sufficient.Integration
Integration pods run scheduled tasks. The standard automatic profile is sufficient.Portal
The Portal module uses ZGC permanently (no automatic profile system). The ZGC safety cap applies — ifMaxRAMPercentage is set above 70%, it is automatically capped at 70%.
Configuration Examples
Automatic Profile (Recommended)
The simplest usage — leaveJAVA_OPTS empty or add only non-GC/heap parameters:
Manual GC Selection
If you want to use a specific GC, specify it inJAVA_OPTS. Automatic GC selection is disabled, but the heap percentage is still automatically set:
Manual Heap Setting
If you want to set the heap percentage yourself:Manual Profile Selection (JVM_MEMORY_PROFILE)
To bypass automatic detection and force a specific profile:Tier-Based Ready Templates
Tier 1 — Development/Test (1 Core / 512 MB):MaxRAMPercentage Safe Limits Table
Troubleshooting
OOM Kill
Symptom: Pod keeps restarting,OOMKilled appears in kubectl describe pod output.
Possible Causes and Solutions:
High GC Pause
Symptom: Response times periodically increase, P99 latency is high. Solutions:- If using G1GC: Increase container memory above 1536 MB (ZGC will be automatically selected) or set
JVM_MEMORY_PROFILE=high - If using Serial GC: Increase container memory or switch to at least
mediumprofile - Adding
-XX:MaxGCPauseMillis=200parameter for G1GC
WARNING Message in Logs
If you see the following message in pod logs:MaxRAMPercentage=80 (or a value above 70%) was set in environment variables, but the automatic profile selected ZGC. The safety cap activated and reduced the heap percentage to 70%.
Solution options:
- Remove the
MaxRAMPercentagesetting fromJAVA_OPTSentirely — the automatic profile selects the optimal value - Explicitly specify the GC:
-XX:+UseG1GC -XX:MaxRAMPercentage=80.0(cap is disabled) - Reduce the
MaxRAMPercentagevalue to 70% or below

