Linux下通过读取/proc/self/status中的VmSize字段可获取进程当前已分配的虚拟内存总量(含mmap、stack、heap等),该值非预警阈值而是快照;ulimit -v设置的RLIMIT_AS上限可通过getrlimit(RLIMIT_AS)获取,但RLIM_INFINITY时无硬性限制,OOM Killer实际依据物理内存+swap总和判定。

Linux下用/proc/self/status读取实际虚拟内存使用量
Linux进程没有“分配临界阈值”这种内核级硬性限制,所谓“阈值”其实是ulimit -v设定的RLIMIT_AS(地址空间上限),或OOM Killer触发前的可用虚拟内存余量。真正能拿到的只有当前已分配的虚拟内存总量,即VmSize字段。直接读/proc/self/status最轻量、无额外依赖:
FILE* f = fopen("/proc/self/status", "r");
char line[256];
while (fgets(line, sizeof(line), f)) {
if (strncmp(line, "VmSize:", 7) == 0) {
long size_kb;
sscanf(line, "VmSize: %ld kB", &size_kb);
printf("Virtual memory used: %ld KB\n", size_kb);
break;
}
}
fclose(f);注意:VmSize包含所有mmap区域(包括未实际分配物理页的lazy分配)、stack、heap、共享库映射等,但不含swap-out部分;它不是“即将爆掉”的预警值,只是快照。
getrlimit(RLIMIT_AS, &rlim)获取用户设置的虚拟内存上限
如果程序被ulimit -v 1048576(1GB)限制过,getrlimit能读到这个软/硬上限。但该值可能为RLIM_INFINITY(表示不限),此时不能当作“安全边界”——因为物理内存+swap总和才是OOM Killer实际参考的依据。
- 软限制(
rlim.rlim_cur)可被进程自行调高(不超过硬限制) - 硬限制(
rlim.rlim_max)需root权限才能提升 - 返回值为0才表示成功;失败时
errno可能是EPERM或EINVAL
示例片段:
立即学习“C++免费学习笔记(深入)”;
struct rlimit rlim;
if (getrlimit(RLIMIT_AS, &rlim) == 0) {
if (rlim.rlim_cur == RLIM_INFINITY) {
printf("No virtual memory limit set\n");
} else {
printf("Soft limit: %ld bytes\n", rlim.rlim_cur);
}
}别信mallinfo或malloc_stats——它们只管堆,不管mmap
很多开发者误以为mallinfo返回的arena+hblkhd能代表总虚拟内存,其实它只统计glibc malloc管理的heap区(brk/sbrk)和mmap分配的小块内存(M_MMAP_THRESHOLD以上才走mmap)。大块内存(如std::vector扩容、new[]大数组、mmap(MAP_ANONYMOUS))完全不计入mallinfo,却真实增加VmSize。
验证方式:写个程序用mmap(NULL, 100分配100MB,再调<code>mallinfo——hblkhd几乎不变,但/proc/self/status里VmSize明显上涨。
生成分析报告的关键是时间序列采样 + 关联上下文
单次读/proc/self/status没意义。真要分析“趋势”,必须定时采集并打点关键操作:
- 每次
new/malloc前/后记一次VmSize - 在
std::vector::reserve()、std::string::resize()等可能触发大分配处埋点 - 记录
clock_gettime(CLOCK_MONOTONIC, &ts)做时间戳,避免wall-clock跳变干扰 - 把数据写入CSV或简易JSON,用Python pandas快速画
VmSizevs 时间曲线
特别注意:频繁读/proc/self/status本身有开销(每次触发内核态copy),建议间隔≥100ms;若需更高频监控,改用perf_event_open跟踪sys_mmap/sys_brk系统调用更精准。
真正的瓶颈往往不在“用了多少”,而在“为什么用这么多”——比如一个std::vector<char></char>反复push_back导致指数扩容,或者忘了clear()就复用容器。这些只能靠代码逻辑审计,不是靠读VmSize数字能发现的。


















