JVM 消耗的本机内存 vs java 进程总内存使用量

Kno*_*Cup 6 java memory operating-system jvm

我有一个小型的 java 控制台应用程序,我想在内存使用方面进行优化。它在 Xmx 设置为仅 64MB 的情况下运行。根据不同的监控工具(htop、ps、pmap、Dynatrace),进程的总体内存使用情况显示值超过 250MB。我主要在 Ubuntu 18 上运行它(也在其他操作系统上进行了测试)。

我使用 -XX:NativeMemoryTracking java param 和 jcmd 的本机内存跟踪来找出为什么在堆之外使用了这么多内存。

NMT 在汇总时显示的值或多或少与 htop 作为常驻内存显示的值相同。

神经机器翻译

Total: reserved=1518873KB, committed=255877KB
Run Code Online (Sandbox Code Playgroud)

顶部

在此输入图像描述

我使用了几个 JVM 参数来减少本机内存消耗(减少堆栈大小、将 GC 更改为串行、类数据共享等)。根据 NMT(malloced 和 mmaped),保留和提交的内存指标总共下降了约 50MB。

神经机器翻译

Total: reserved=1475110KB, committed=209218KB
Run Code Online (Sandbox Code Playgroud)

我使用的所有工具(htop、ps、pmap、Dynatrace)都没有显示任何差异。该进程使用的总内存仍然是 250MB。

  1. 问题是,这是为什么呢?为什么减少 JVM 的本机内存使用量不会对 java 进程使用的常驻内存产生任何影响?它是否预先以某种方式保留并且未释放?
  2. 有没有其他方法可以有效减少整个java进程的内存消耗(在已经优化并设置为仅64MB的堆之外)?

apa*_*gin 7

由于多种原因,NativeMemoryTracking 报告的提交内存可能少于进程的实际驻留集大小 (RSS)。

  • NMT 仅计算某些 JVM 结构。它不计算内存映射文件(包括加载的 .jar 文件),也不计算除libjvm. 即使是由标准类库(即libjava)分配的本机内存也不会在 NMT 报告中显示。

  • 当某些东西使用标准系统分配器(malloc)分配内存然后释放它时,该内存并不总是返回给操作系统。系统分配器可能会将释放的内存保留在池中以供将来重用,但从操作系统的角度来看,该内存被视为已使用(因此包含在 RSS 中)。

这个答案这个视频可能会让您了解还有什么会占用内存,以及如何分析 Java 进程的占用空间。

这篇文章描述了一些关于减少足迹的想法(合理的和极端的)。