首页 > 解决方案 > 如何找到在 Linux 环境中可用的用户空间内存量?

问题描述

CONFIG_VMSPLIT_1G在我的 32 位 Linux 映像中使用配置。所以 3GB 的虚拟地址空间分配给内核,1GB 的虚拟地址空间分配给用户空间。现在,如果我在用户空间中运行 stressapptest 并使用 cat 显示 80% 的可用内存/proc/meminfo,它会抛出一个错误,提示“无法分配内存”。

有没有办法找到为用户空间分配了多少 excat 虚拟地址空间?

root@:/#
root@:/# cat /proc/meminfo | head -5
MemTotal:        1826896 kB
MemFree:         1708308 kB
MemAvailable:    1694060 kB
Buffers:            2484 kB
Cached:             9520 kB
root@:/#
root@:/# ./stressapptest -M 900
2021/09/25-06:48:59(UTC) Log: Commandline - ./stressapptest -M 900
2021/09/25-06:48:59(UTC) Stats: SAT revision 1.0.7_autoconf, 32 bit binary
2021/09/25-06:48:59(UTC) Log: varada @ CHEPSSW01 on Wed Aug 27 12:05:13 IST 2014 from open source release
2021/09/25-06:48:59(UTC) Log: 1 nodes, 4 cpus.
2021/09/25-06:48:59(UTC) Log: Defaulting to 4 copy threads
2021/09/25-06:48:59(UTC) Log: Flooring memory allocation to multiple of 4: 900MB
2021/09/25-06:48:59(UTC) Log: Prefer plain malloc memory allocation.
2021/09/25-06:48:59(UTC) Process Error: memalign returned 0
2021/09/25-06:48:59(UTC) Process Error: failed to allocate memory
2021/09/25-06:48:59(UTC) Process Error: Sat::Initialize() failed
2021/09/25-06:48:59(UTC)
2021/09/25-06:48:59(UTC) Status: FAIL - test encountered procedural errors
2021/09/25-06:48:59(UTC)
2021/09/25-06:48:59(UTC) Process Error: Fatal issue encountered. See above logs for details.
root@OpenWrt:/#

标签: memorymemory-managementlinux-kernelvirtual-address-spaceos-userspace

解决方案


每个进程都有不同的虚拟地址空间,您没有全局“用户空间”虚拟地址空间。VMSPLIT_1G所做的只是限制用户空间程序可用的虚拟地址范围。您可以很好地拥有多个程序,其中映射了整个 1G 可用虚拟地址空间,但仍然有可用内存,因为这些页面实际上并不驻留在主内存中。

如果您想查看当前使用了多少内存,那么/proc/meminfo这就是您要查找的内容,但请记住,您必须在程序运行时检查它,而不是在运行之前/之后,因为那样会毫无意义。根据各个进程,您拥有/proc/[PID]/stat并且/proc/[PID]/status它们都提供“驻留集大小”(实际驻留在主内存中的已用虚拟内存内存量),或者您可以查看/proc/[PID]/maps特定进程使用的虚拟地址。

现在,如果我在用户空间中运行 stressapptest 并使用 cat 显示 80% 的可用内存/proc/meminfo,它会引发错误

这似乎在你的配置中是意料之中的,它可能由于不同的原因而发生,最有可能的一个是程序试图请求一个太大的内存块,以及程序使用的内存分配器(即 Glibc 的malloc)无法分配一个,因此即使在技术上仍有一些可用内存可供使用,它也会返回失败。

例如,即使您有很多空闲的主内存,但您的进程有一个几乎已满的虚拟地址,并且您尝试做一个mmap大小太大的单个,内核将无法容纳这些连续的虚拟内存块中有许多页面,并且将返回失败。


推荐阅读