如何从崩溃的应用程序中释放大页内存。

11
我有一个使用巨页的应用程序,由于某些错误,该应用程序突然崩溃了。 崩溃后,由于应用程序未能正确释放巨页,因此在sys文件系统中,空闲的巨页数量没有增加。
$ sudo cat /sys/kernel/mm/hugepages/hugepages-2048kB/free_hugepages 
0
$ sudo cat /sys/kernel/mm/hugepages/hugepages-2048kB/nr_hugepages 
1024

有没有一种方式可以强制释放大页面?
5个回答

8

有时需要检查是否已挂载所有的hugetlbfs目录。

  1. 通过命令mount | grep huge查找已挂载的目录。

  2. 检查每个目录,除了特别的/dev/hugepages目录。

  3. 删除所有2M大小的文件。(2M是hugepage的大小)


2
使用ipcs -m命令列出共享内存段。 使用ipcrm命令删除剩余的共享内存段。
2019年6月24日编辑: 好的,上面的答案虽然在一定程度上是正确的,但有点简略。特别是,如果您有一个具有多个DB实例的主机,并且只有一个崩溃了,那么如何确定应清除哪些(如果有的话)内存段呢?
这也可以做到。对于每个正在运行的实例,请使用/ as sysdba连接,然后执行oradebug setmypid(任何pid都可以,因为所有Oracle PIDs都连接到SGA)。然后执行oradebug ipc。这将(希望)返回IPC信息写入跟踪文件。因此,转到udump(或diag_dest)目录,并查找您的跟踪文件。它将包含实例的所有IPC信息。这将包括 ShmId 。浏览文件以查找该实例正在使用的ShmId(s)。现在查看 ipcs -m 的输出。
当您为所有正在运行的实例完成此操作时, ipcs -m 输出的任何内存段都显示非零内存分配,并且您无法在任何运行实例的 oradebug ipc 信息中解释它/它们,必须是崩溃实例的剩余内存段。使用 ipcrm 删除它/它们。
在具有多个运行实例的主机上执行此操作时,可能会有点棘手。请小心进行。您不想删除正在运行的实例的SGA!
希望对您有所帮助....

嗨,马克,能否确定哪个shmid映射到哪个hugepage文件?因为在某些情况下,崩溃的应用程序可能只使用一个或两个hugepages... ipcrm似乎有点过于激进了。你有什么想法吗? - HCSF
1
嗨,如果您正在运行多个实例,可能会有些棘手。解决方案(有点繁琐)是连接到每个运行的实例,并使用“oradebug”确定运行实例的SHMID。然后通过排除法,您无法识别的那些必须来自崩溃的实例。然后使用“ipcrm”仅删除这些内存段。完整细节将在几分钟内更新的答案中提供。 - Mark J. Bobak

1
如果您按照以下说明操作,就可以摆脱已分配的巨大页面:
1)让我们检查重启时空闲的巨大页面。
dpdk@dpdkvm:~$ ls /mnt/huge/
empty

dpdk@dpdkvm:~/dpdk-1.8.0/examples/kni$ cat /proc/meminfo
...
HugePages_Total:     256
HugePages_Free:      256
...

2) 使用错误的参数启动dpdk应用程序,会产生错误。

dpdk@dpdkvm:~/dpdk-1.8.0/examples/kni$ sudo ./build/kni -c 0x03 -n 2 -- -P -p 0x03 --config="(0,0,1),(1,0,1)"
...
EAL: Error - exiting with code: 1
  Cause: No supported Ethernet device found

3) 当我检查 hugepages 时,没有任何空闲。

dpdk@dpdkvm:~/dpdk-1.8.0/examples/kni$ cat /proc/meminfo
...
HugePages_Total:     256
HugePages_Free:        0
...

4) 现在,当我检查挂载的巨页目录时,我可以看到那些没有被 dpdk 应用程序归还给操作系统的文件。

dpdk@dpdkvm:~/dpdk-1.8.0/examples/kni$ ls /mnt/huge/
...
rtemap_0    rtemap_137  rtemap_176  rtemap_214  rtemap_253  rtemap_62
...

5) 最后,如果您删除以rtemap开头的文件,则可以归还hugepages

dpdk@dpdkvm:~/dpdk-1.8.0/examples/kni$ sudo rm /mnt/huge/*
[sudo] password for dpdk:
dpdk@dpdkvm:~/dpdk-1.8.0/examples/kni$ cat /proc/meminfo
...
HugePages_Total:     256
HugePages_Free:      256
...

1
HugeTLB可用于共享内存(Mark J. Bobak的回答将处理此问题),或应用程序在HugeTLB文件系统中mmap创建的文件。如果应用程序崩溃而没有删除这些文件,则它们会继续存在并保留相应的内存“已分配”状态。检查HugeTLB文件系统,看看是否有应用程序留下的文件。删除它们将释放内存。

如果我在某个正在使用这些大页的程序运行时这样做会发生什么? - sudo
1
Linux使用文件描述符的引用计数。如果某个应用程序仍然打开该文件,则该文件将从目录中删除,但是文件描述符和底层的大页面将保持有效,直到关闭最后一个打开的描述符为止。 - ArtemB

-3
你的 hugetlb 可能被共享内存或 mmap 文件所使用。 尝试移除共享内存或卸载 hugetlb 文件系统。

1
这些建议在之前的回答中已经提到了;这个回复似乎没有添加任何新内容。 - Prune

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接