为什么 free 报告的已用内存比 top 报告的单个进程的常驻使用量少得多?

为什么 free 报告的已用内存比 top 报告的单个进程的常驻使用量少得多?

我有一个可能存在问题的应用程序可能存在内存泄漏问题。然而,在调查此问题的过程中,我发现了一些似乎相互矛盾的信息。

当我用来free获取服务器上的内存使用情况摘要时,似乎有足够的可用 RAM:

[alice@myserver]$ free -h
              total        used        free      shared  buff/cache   available
Mem:           9.8G        2.4G        131M        3.6G        7.2G        3.5G
Swap:            0B          0B          0B

但是,如果我使用 top 来检查感兴趣的进程,它会显示单个进程使用了​​几乎所有的可用 RAM:

  PID USER      PR  NI    VIRT    RES    SHR S  %CPU %MEM     TIME+ COMMAND
16907 alice     20   0  158.6g   9.1g   7.6g S  63.2 92.8   6476:48 my_task

即使我计算所有的已用(2.4G)和共享(3.6G),也仍然只有 6.0G,比这个单个进程使用的 9.1G 少得多。

我相信哪一个,top或者free

以下为一些相关附加详细信息:

  • 操作系统是 CentOS 7.7
  • my_task 是一个运行 JDK 15 的 Java 应用程序,中关村
  • my_task 使用 JNI 并分配了大量堆外内存(预计为 1-2GB,而不是 4 或 5GB)
  • 最大堆大小为 3GB,但 VisualVM 显示总堆大小约为 2GB,仅分配了约 1GB

答案1

事实证明top这是错误的,这是由于 ZGC 造成的。

为了避免掩码指针的开销,ZGC 采用了多重映射技术。多重映射是将多段虚拟内存映射到同一段物理内存。

ZGC使用Java堆的3个视图(“marked0”,“marked1”,“remapped”),即3种不同“颜色”的堆指针和同一个堆的3个虚拟内存映射。

因此,操作系统可能会报告内存使用量增加了 3 倍。

https://stackoverflow.com/questions/57899020/zgc-max-heap-size-exceed-physical-memory https://stackoverflow.com/questions/62926652/the-java-zgc-garbage-collector-uses-a-lot-of-memory

相关内容