java 应用程序的巨大系统内存使用量与堆使用量相比
Huge system memory usage of java applications compared to heap usage
我有一个类似 java 框架的微服务。许多 java 在单个盒子上处理 运行 (ubuntu 14.04.4 LTS)。 java 进程使用大量系统内存,因此交换区 space 被大量使用。 jstat gc 报告不解释系统内存使用情况。所有 java 进程 运行 参数
-XX:MinHeapFreeRatio=20 -XX:MaxHeapFreeRatio=40 -XX:GCTimeRatio=4 -XX:AdaptiveSizePolicyWeight=90
强制 JVM 将内存还给系统。没有参数,问题仍然存在。一些 java 组件使用 nashorn 引擎来编写某些功能的脚本。
有人可以解释这里的行为吗?
是否有任何 jvm 参数限制巨大的系统内存使用?
如何命令 OS 对 jvm 的内存分配更严格?
一些数据:
组件 A(带 nashorn)
顶部:
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
2400 xxxxxx 20 0 13.933g 807496 7332 S 0.0 2.5 4180:15 java
jstat -gc 2400:
S0C S1C S0U S1U EC EU OC OU MC MU CCSC CCSU YGC YGCT FGC FGCT GCT
512.0 512.0 0.0 400.0 19456.0 12751.6 62464.0 59862.3 89688.0 84866.6 10624.0 9440.4 2165265 15977.896 16816 1813.836 17791.732
- 容量:约180MB
- 用法:大约165MB
- 系统资源:ca。 800 MB
为什么组件使用了 4 倍于 GC 区域的内存?
组件 B(没有 nashorn)
顶部:
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
19476 xxxx 20 0 13.465g 120436 7836 S 7.0 0.4 22:40.76 java
jstat -gc 19476:
S0C S1C S0U S1U EC EU OC OU MC MU CCSC CCSU YGC YGCT FGC FGCT GCT
512.0 512.0 0.0 0.0 41472.0 25408.7 343040.0 7164.5 17664.0 17183.1 2048.0 1919.4 3650 10.806 939 16.788 27.594
- 容量:约403MB
- 用法:大约52MB
- 系统资源:120 MB
此处GC区域容量大于实际系统内存使用量。系统内存使用量仍然是 GC 区域的两倍。 IMO 此组件行为正常,因为库等也部分映射到内存中。
组件 C(没有 nashorn)
顶部:
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
2272 xxxxxx 20 0 13.382g 922944 11108 S 0.7 2.8 40033:41 java
jstat -gc 2272:
S0C S1C S0U S1U EC EU OC OU MC MU CCSC CCSU YGC YGCT FGC FGCT GCT
1024.0 1024.0 868.0 0.0 36352.0 23866.1 76800.0 56580.2 68864.0 64571.1 8448.0 7460.6 31974159 199295.501 844692 134644.040 333939.541
- 容量:约190MB
- 用法:大约152MB
- 系统资源:920 MB
为什么组件使用的内存是 GC 区域内存的 6 倍?
Can someone explain the behavior here?
内存使用没有单一的解释,有很多影响因素。
- 使用NMT了解JVM内部各部分分配了多少内存
- 使用
pmap -x <pid>
识别内存映射文件。
- 获取堆转储以查找直接内存缓冲区(它们只是显示为 pmap 中的一些
[anon]
映射)或使用 Yourkit which has a memory inspection to identify the amount allocated by direct buffers. At runtime you can use BufferPoolMXBean 跟踪直接缓冲区使用。
除此之外,您还必须考虑到每个 JVM 都有一些基准内存消耗和垃圾收集器需要的喘息空间。 运行 共享 JVM 中的多个服务可以分摊这些基线成本。
由于虚拟内存系统的复杂性,您还需要了解 。
Are there any jvm patameters that restrict the huge system memory usage?
这取决于原因。
对于托管堆,可以 make it yield unused memory back to the OS more swiftly,但会降低性能。
我有一个类似 java 框架的微服务。许多 java 在单个盒子上处理 运行 (ubuntu 14.04.4 LTS)。 java 进程使用大量系统内存,因此交换区 space 被大量使用。 jstat gc 报告不解释系统内存使用情况。所有 java 进程 运行 参数
-XX:MinHeapFreeRatio=20 -XX:MaxHeapFreeRatio=40 -XX:GCTimeRatio=4 -XX:AdaptiveSizePolicyWeight=90
强制 JVM 将内存还给系统。没有参数,问题仍然存在。一些 java 组件使用 nashorn 引擎来编写某些功能的脚本。
有人可以解释这里的行为吗?
是否有任何 jvm 参数限制巨大的系统内存使用?
如何命令 OS 对 jvm 的内存分配更严格?
一些数据:
组件 A(带 nashorn)
顶部:
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
2400 xxxxxx 20 0 13.933g 807496 7332 S 0.0 2.5 4180:15 java
jstat -gc 2400:
S0C S1C S0U S1U EC EU OC OU MC MU CCSC CCSU YGC YGCT FGC FGCT GCT
512.0 512.0 0.0 400.0 19456.0 12751.6 62464.0 59862.3 89688.0 84866.6 10624.0 9440.4 2165265 15977.896 16816 1813.836 17791.732
- 容量:约180MB
- 用法:大约165MB
- 系统资源:ca。 800 MB
为什么组件使用了 4 倍于 GC 区域的内存?
组件 B(没有 nashorn)
顶部:
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
19476 xxxx 20 0 13.465g 120436 7836 S 7.0 0.4 22:40.76 java
jstat -gc 19476:
S0C S1C S0U S1U EC EU OC OU MC MU CCSC CCSU YGC YGCT FGC FGCT GCT
512.0 512.0 0.0 0.0 41472.0 25408.7 343040.0 7164.5 17664.0 17183.1 2048.0 1919.4 3650 10.806 939 16.788 27.594
- 容量:约403MB
- 用法:大约52MB
- 系统资源:120 MB
此处GC区域容量大于实际系统内存使用量。系统内存使用量仍然是 GC 区域的两倍。 IMO 此组件行为正常,因为库等也部分映射到内存中。
组件 C(没有 nashorn)
顶部:
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
2272 xxxxxx 20 0 13.382g 922944 11108 S 0.7 2.8 40033:41 java
jstat -gc 2272:
S0C S1C S0U S1U EC EU OC OU MC MU CCSC CCSU YGC YGCT FGC FGCT GCT
1024.0 1024.0 868.0 0.0 36352.0 23866.1 76800.0 56580.2 68864.0 64571.1 8448.0 7460.6 31974159 199295.501 844692 134644.040 333939.541
- 容量:约190MB
- 用法:大约152MB
- 系统资源:920 MB
为什么组件使用的内存是 GC 区域内存的 6 倍?
Can someone explain the behavior here?
内存使用没有单一的解释,有很多影响因素。
- 使用NMT了解JVM内部各部分分配了多少内存
- 使用
pmap -x <pid>
识别内存映射文件。 - 获取堆转储以查找直接内存缓冲区(它们只是显示为 pmap 中的一些
[anon]
映射)或使用 Yourkit which has a memory inspection to identify the amount allocated by direct buffers. At runtime you can use BufferPoolMXBean 跟踪直接缓冲区使用。
除此之外,您还必须考虑到每个 JVM 都有一些基准内存消耗和垃圾收集器需要的喘息空间。 运行 共享 JVM 中的多个服务可以分摊这些基线成本。
由于虚拟内存系统的复杂性,您还需要了解
Are there any jvm patameters that restrict the huge system memory usage?
这取决于原因。
对于托管堆,可以 make it yield unused memory back to the OS more swiftly,但会降低性能。