容器内堆外的Java内存



我一直在研究和阅读一些关于内存使用的问题,即使这里有很好的答案,我也想尝试理解我在分析中收集的一些值。

我在下面写的代码只是为了显示我在哪里收集数据。注意:这些代码不是编译的,只是为了理解。

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);

这是我收集的一些数据:集装箱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
}
}

集装箱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
}
}

我运行的是:

  • 高山公开赛jdk-11
  • 容器内存限制:2GB
  • AWS-EKS
  • JVM环境:-Djava.net.prpreferPv4Stack=true-XX:InitialRAMPercentage=70.0-XX:MaxRAMPercentage=85.0-Dfile.concoding=UTF8

我注意到;operationSystem.totalPhysicalMemorySizeMB";是JVM认为可使用的内存量。

参数"-XX: MaxRAMPercentage=85.0〃;工作如预期。(参考1907年(

我知道nonHeap内存是堆外的,那么我应该使用nonHeap+heap来计算应用程序的总使用量吗。

问题:我主要怀疑的是"freePhysicalMemorySizeMB";,即使提交的内存(堆+nonHeap(具有相同的值,这个值在容器之间也会有很大的变化。

我读到java可以使用Native Library(JNI(,这也会消耗内存。

  • 我是否应该保留超出heap+NonHeap估计的更多内存?如果是,有可能知道多少吗?垃圾回收器会清除这些其他使用过的内存吗?

  • 是";NonHeap";与";堆外";?

注意:我的pod只是在运行java应用程序(以及alpine本身(

我应该使用nonHeap+heap来计算应用程序的总使用量吗。

否。Java进程使用的总物理内存包括许多JVM没有计算在内的东西
有关详细信息,请参阅此答案和此演示文稿。

我的主要疑虑是;freePhysicalMemorySizeMB";,即使提交的内存(堆+nonHeap(具有相同的值,这个值在容器之间也会有很大的变化。

只是不要看getFreePhysicalMemorySize()。此值很少有用。它没有考虑页面缓存和各种可回收的操作系统结构,当应用程序请求更多内存时,这些结构可以自动释放。

衡量进程内存使用率的最有意义的指标是RSS——驻留大小。在Linux上查找应用程序自己的RSS的一个简单方法是读取/proc/self/stat

我是否应该保留超出heap+NonHeap估计的更多内存?如果是,有可能知道多少吗?

应用程序可能需要比堆+非堆更多的内存。静态地猜测正确的数字并不容易,所以你最好的选择是观看实际的RSS并相应地调整限制。

这是术语";NonHeap";与";堆外";?

取决于上下文。例如,在jconsole和其他一些工具中,Non-Heap表示某些JVM结构:元空间、压缩类空间和代码缓存。Off-heap通常是一个更宽泛的术语,它基本上意味着除Java堆之外的所有内容。

最新更新