You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C++内存分配失败处理程序在不同Ubuntu版本行为差异求助

问题:Ubuntu 22.04与18.04上C++ new handler行为差异原因

我是C新手,跟随《Thinking in C》编写了一段设置new handler处理内存分配失败的代码。在我的Ubuntu 22.04LTS笔记本上,程序未触发void out_of_memory定义的预期错误输出,仅显示“Killed”;但在Ubuntu 18.04LTS服务器上,程序能正常输出“memory exhausted after 8946078 allocations!”。请问为何两台系统上程序行为不同?

测试代码

// Changing the new-handler
#include <iostream>
#include <cstdlib>
#include <new>
using namespace std;

int count = 0;

void out_of_memory() {
  cerr << "memory exhausted after " << count 
    << " allocations!" << endl;
  exit(1);
}

int main() {
  set_new_handler(out_of_memory);
  while(1) {
    count++;
    new int[1000]; // Exhausts memory
  }
}

不同系统输出

Ubuntu 22.04 LTS笔记本输出

Killed

Ubuntu 18.04 LTS服务器输出

memory exhausted after 8946078 allocations!

原因分析

核心差异源于Linux内核的**OOM Killer(内存不足终止器)**行为和内存分配策略的版本变化:

  • OOM Killer触发时机不同:Ubuntu 22.04搭载的内核版本更高,OOM Killer的触发逻辑更激进。当程序快速循环申请内存时,系统会更早判定该进程占用过多资源,直接终止进程,完全没等到new运算符分配失败、触发new handler的时机。而Ubuntu 18.04的内核OOM Killer触发阈值更高,程序有机会耗尽系统内存(含交换空间),让new分配失败,从而执行定义的out_of_memory函数。

  • 内存过度分配策略的影响:Linux默认允许进程申请比实际可用内存更多的空间(过度分配),但仅在进程真正使用内存时才分配物理页。新版本系统在内存接近耗尽时,会更快触发OOM Killer回收资源;旧版本则会让进程继续尝试分配,直到物理内存+交换空间完全耗尽,才会让new返回分配失败。

  • 内存申请速度的影响:代码每次申请4KB内存(1000个int),循环速度极快。新版本系统的内存监控机制更灵敏,在new还没来得及返回失败状态前,就已经启动OOM Killer终止了进程。

内容的提问来源于stack exchange,提问作者Yiwei Jiang

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.26 19:07:10