内存不足问题

内存不足问题

我在配备 32 GB RAM 和 Nvidia K80 GPU 的 Dell PowerEdge R730 上运行 Ubuntu 14.04LTS。我有一个可以运行很长时间的 Python 脚本,但实际上只是对其他程序进行了一堆相对短暂的系统调用(其中一些程序在必要时会广泛使用 CUDA)。除了总体 Python 脚本之外,各个系统调用每个只运行大约 45 秒,并且 Python 脚本本身不会“维护”任何东西 - 它只进行系统调用和迭代 - 而不是任何结果存储等。

当我观察程序运行并用“top”监控内存使用情况时,我看到报告的“可用”内存随着时间的推移而减少。我知道这通常不是一个问题,因为使用了缓存。但最终,机器挂起并且不以任何方式响应(即控制台上没有鼠标光标移动,远程终端没有响应等)。当这种情况发生时,我必须硬重启系统,然后一切恢复正常,我可以从上次中断的地方继续,直到它再次挂起。

另一个有趣的点是 - 经过足够的重启后,程序终于完成了。同样,在此之后,系统上没有任何重要的程序在运行,但是,gnome-system-monitor 和 top 都报告内存使用量几乎已满,并且尝试运行其他(最小)命令经常被内核“杀死”。检查系统日志,它报告“内存不足”,这似乎表明正在使用的内存不是缓存,而是实际“声明”的内存。问题是 - 由谁?检查人们在这个论坛和其他论坛上提到的所有内存实用程序,没有进程声称正在使用大量内存。

我读过有关内核内存泄漏的报告,这就是我想要声称的,但这似乎不太可能。

问:如何确定什么占用了所有内存? 我希望能够确定它是否在内核中或者是否正在运行某个进程。

支持信息:

uname -a:

Linux machinename 3.19.0-47-generic #53~14.04.1-Ubuntu SMP Mon Jan 18 16:09:14 UTC 2016 x86_64 x86_64 x86_64 GNU/Linux

lscppu:

Architecture:          x86_64
CPU op-mode(s):        32-bit, 64-bit
Byte Order:            Little Endian
CPU(s):                8
On-line CPU(s) list:   0-7
Thread(s) per core:    2
Core(s) per socket:    4
Socket(s):             1
NUMA node(s):          1
Vendor ID:             GenuineIntel
CPU family:            6
Model:                 63
Stepping:              2
CPU MHz:               1200.351
BogoMIPS:              5993.09
Virtualization:        VT-x
L1d cache:             32K
L1i cache:             32K
L2 cache:              256K
L3 cache:              10240K
NUMA node0 CPU(s):     0-7

事先阅读和理解:我读过大量关于理解 Linux 内存使用和报告的帖子。我知道,当像 top 这样的程序报告“可用”内存很少时,这并不一定是问题,因为大部分“已用”内存都被缓存了,而实际上,让 RAM 充满缓存的内容是件好事。但我相信,这不是我看到的问题,因为如果它是缓存,程序似乎可以利用它。内核正在介入并终止新进程,dmesg 报告系统“内存不足”,这似乎表明内存正在以非缓存的方式被占用,但在我尝试过的任何内存分析工具中似乎都没有报告这种情况。

更新:根据下面的答案,当事情开始变糟时,我查看了 /proc/meminfo,虽然我不知道这些都是什么意思,但有几个似乎..可疑..“DirectMap2M”似乎有问题,“VmallocChunk”也是如此,尽管问题不那么严重...

> cat /proc/meminfo
MemTotal:       32828728 kB
MemFree:          166568 kB
MemAvailable:     100656 kB
Buffers:            6520 kB
Cached:            27416 kB
SwapCached:          300 kB
Active:            17904 kB
Inactive:          16076 kB
Active(anon):        360 kB
Inactive(anon):      212 kB
Active(file):      17544 kB
Inactive(file):    15864 kB
Unevictable:          32 kB
Mlocked:              32 kB
SwapTotal:      33452028 kB
SwapFree:       33317332 kB
Dirty:                 0 kB
Writeback:             0 kB
AnonPages:           484 kB
Mapped:            23276 kB
Shmem:               144 kB
Slab:             559236 kB
SReclaimable:      60016 kB
SUnreclaim:       499220 kB
KernelStack:        8864 kB
PageTables:        10132 kB
NFS_Unstable:          0 kB
Bounce:                0 kB
WritebackTmp:          0 kB
CommitLimit:    49866392 kB
Committed_AS:    1143048 kB
VmallocTotal:   34359738367 kB
VmallocUsed:      358064 kB
VmallocChunk:   34342563088 kB
HardwareCorrupted:     0 kB
AnonHugePages:         0 kB
CmaTotal:              0 kB
CmaFree:               0 kB
HugePages_Total:       0
HugePages_Free:        0
HugePages_Rsvd:        0
HugePages_Surp:        0
Hugepagesize:       2048 kB
DirectMap4k:    32637928 kB
DirectMap2M:    18446744073709318144 kB
DirectMap1G:     3145728 kB

更新2刚刚再次运行程序,每 15 秒捕获一次 cmd“free”。我观察到 free 列随着程序的运行而下降,直到达到一个非常低的值(大约 190000),当它达到该水平时,程序挂起,一切开始变得非常缓慢。我按下 ctrl-c 键,在程序挂起一段时间后,最终终端响应并带我回到提示符。但是,“free”仍然在 free 列中报告大约 190000,甚至一般使用(只是在终端中输入)也非常慢 - 当前没有程序正在运行。查看 /proc/meminfo,“DirectMap2M”字段再次变得疯狂。我也定期捕获 /proc/meminfo 的内容,并可以查看情况随时间的变化。

仅供参考:当挂断时,以下是“free”命令的输出:

             total       used       free     shared    buffers     cached
Mem:      32828728   32636496     192232          4       7368      22972
-/+ buffers/cache:   32606156     222572
Swap:     33452028     205160   33246868

这是来自 /proc/meminfo 的 DirectMap2M 值随时间变化的图。在图中的最右侧点之后,它变为一个非常大的值 - 看起来像是下溢。在谷歌上搜索了一下,发现其他人也遇到了下溢问题。但我不知道 DirectMap2M 代表什么。

在此处输入图片描述

更新 3: 仍在与此作斗争。一些最近发现的信息需要添加:

我们尽可能将其归结为以下内容:

#include "cublas_v2.h"
int main() {
  cublasHandle_t handle;
  cublasCreate(&handle);
  cublasDestroy(handle);
  return 0;
}

每次我们在配备 NVidia K40 的 Dell T630 上运行该程序时,我们都会发现 DirectMap2M 出现故障。如果运行次数足够多,我们会看到下溢问题,并且必须重新启动机器。我们还有一台配备 NVidia K80 的 Dell R730,它会出现同样的行为。

有趣的是,我们还有另一台计算机(一台配备 NVidia GTX980M 的笔记本电脑)运行相同的 Ubuntu 内核,当我们运行上述程序时我们没有观察到这种行为。

答案1

一个好的起点是跟踪 /proc/meminfo 中的统计数据,其中包含大量有关全局内存利用率的详细信息。我建议定期(例如每 30 分钟左右)捕获 /proc/meminfo 的输出,然后可以检查它以查看内存分配增长发生的位置。从那以后,您至少会对下一步该看什么有所了解。

答案2

我们在使用 GTX 970 和 GTX 980Ti GPU 的 Debian Jessie 机器上运行 CUDA 作业时也遇到了同样的问题。您的测试用例也导致我们的机器在几分钟内内存耗尽。

最终,我们解决了这一恼人行为,方法是安装 nvidia 最新的测试版驱动程序(撰写本文时为 364.12 版)。它似乎独立于 Linux 内核(我们尝试了几个)和 CUDA 版本(我们也尝试了几个)。这似乎是 nvidia 驱动程序本身的一个错误,最近才得到修复。

相关内容