I have been studying and reading some questions about memory usage, even with good answers here I would like to try understading some values that I have collected in my analysis.
I wrote this below code just to show where I collected the data. Note: This codes does not compile, it is just to understand.
long KB_FACTOR = 1024;
long MB_FACTOR = 1024 * KB_FACTOR;
OperatingSystemMXBean os = (com.sun.management.OperatingSystemMXBean) ManagementFactory.getOperatingSystemMXBean();
"operationSystem.totalPhysicalMemorySizeMB" = os.getTotalPhysicalMemorySize() / MB_FACTOR);
"operationSystem.freePhysicalMemorySizeMB" = os.getFreePhysicalMemorySize() / MB_FACTOR);
long freeMemoryBytes = Runtime.getRuntime().freeMemory();
long totalMemoryBytes = Runtime.getRuntime().totalMemory();
long maxMemoryBytes = Runtime.getRuntime().maxMemory();
"memory.maxMB" = (maxMemoryBytes / MB_FACTOR);
"memory.freeMB" = (freeMemoryBytes / MB_FACTOR);
"memory.totalMB" = (totalMemoryBytes / MB_FACTOR);
MemoryMXBean memoryMXBean = ManagementFactory.getMemoryMXBean();
MemoryUsage heapMemoryUsage = memoryMXBean.getHeapMemoryUsage();
"memoryHeap.commitedMB" = (heapMemoryUsage.getCommitted() / MB_FACTOR);
"memoryHeap.maxMB" = (heapMemoryUsage.getMax() / MB_FACTOR);
MemoryUsage nonHeapMemoryUsage = memoryMXBean.getNonHeapMemoryUsage();
"memoryNonHeap.commitedMB" = (nonHeapMemoryUsage.getCommitted() / MB_FACTOR);
"memoryNonHeap.maxMB" = (nonHeapMemoryUsage.getMax() / MB_FACTOR);
"memoryHeap+NonHeap.committedMB" = (heapMemoryUsage.getCommitted() / MB_FACTOR) + (nonHeapMemoryUsage.getCommitted() / MB_FACTOR);
This is some data I have collected: Container 01
{
"memory": {
"freeMB": 611,
"maxMB": 1622,
"totalMB": 1336
},
"memoryHeap": {
"committedMB": 1336,
"maxMB": 1622
},
"memoryNonHeap": {
"initMB": 7,
"usedMB": 219,
"committedMB": 227,
"maxMB": 0
},
"memoryHeap+NonHeap": {
"committedMB": 1563
},
"operationSystem": {
"totalPhysicalMemorySizeMB": 1907,
"freePhysicalMemorySizeMB": 390
}
}
Container 02:
{
"memory": {
"freeMB": 303,
"maxMB": 1622,
"totalMB": 1336
},
"memoryHeap": {
"committedMB": 1336,
"maxMB": 1622
},
"memoryNonHeap": {
"committedMB": 244,
"maxMB": 0
},
"memoryHeap+NonHeap": {
"committedMB": 1580
},
"operationSystem": {
"totalPhysicalMemorySizeMB": 1907,
"freePhysicalMemorySizeMB": 87
}
}
I am running with:
- alpine openjdk-11
- Container memory limit: 2GB
- AWS EKS.
- JVM Env: -Djava.net.preferIPv4Stack=true -XX:InitialRAMPercentage=70.0 -XX:MaxRAMPercentage=85.0 -Dfile.encoding=UTF8
I have noticed that "operationSystem.totalPhysicalMemorySizeMB" is the amount of memory JVM understand as available to use.
The parameter "-XX:MaxRAMPercentage=85.0" work as expected. (using 1,907 as reference)
I know that nonHeap memory is off-heap, then should I use nonHeap+heap to calculate the total usage by my application.
Question: My main doubt is about "freePhysicalMemorySizeMB", this value variates a lot between containers even when the committed memories (heap+nonHeap) have the same value .
I read that java can use Native Library (JNI) and this also consume memory.
Should I reserve more memory beyond the estimate of heap+NonHeap? If yes, is it possible to know how much? Will Garbage Collector clear these others used memory?
Is it the term "NonHeap" the same as "off-heap"?
Note: My pod is just running java application (and alpine itself)