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

Linux进程启动时默认分配的堆内存大小是多少?

探究Linux进程启动时默认堆内存分配行为

我最近关注的不是ulimit相关内容,而是Linux进程启动时默认堆内存的分配大小问题。下面是我的测试过程和发现:

初始测试:用strace观察堆分配

我先用g++ -O0 -Wall -std=c++11编译了一段简单的C++代码,尝试通过strace工具追踪new和delete操作时的系统调用,结果却没观察到堆分配相关的变化——这是因为小内存分配通常不会触发内核级的系统调用,而是从libc预分配的堆空间中直接取用。

初始测试代码

#include <iostream>
using namespace std;
class C {
public:
    int i;
};
int main() {
    cout << "possible heap allocation below:" << endl;
    auto c = new C;
    auto i = c->i;
    delete c;
    cout << "Was anything revealed above?" << endl;
    cout << "i = " << i << endl;
}

优化测试:用ltrace和mallinfo精准观察

后来调整了测试方法,改用ltrace追踪libc运行时的行为,同时借助mallinfo结构体来打印堆内存的详细统计信息,这样就能清晰看到libc预分配的空间,以及new/delete操作带来的空间变化了。

优化后的测试代码

#include "malloc.h"
#include <cstdio>
class C {
public:
    int i;
};
void prnt(struct mallinfo info) {
    printf("Non-mmapped space allocated (bytes) : %d\n", info.arena);
    printf("Number of free chunks : %d\n", info.ordblks);
    printf("Number of free fastbin blocks : %d\n", info.smblks);
    printf("Number of mmapped regions : %d\n", info.hblks);
    printf("Space allocated in mmapped regions (bytes): %d\n", info.hblkhd);
    printf("Maximum total allocated space (bytes) : %d\n", info.usmblks);
    printf("Space in freed fastbin blocks (bytes) : %d\n", info.fsmblks);
    printf("Total allocated space (bytes) : %d\n", info.uordblks);
    printf("Total free space (bytes) : %d\n", info.fordblks);
    printf("Top-most, releasable space (bytes) : %d\n", info.keepcost);
}
int main() {
    struct mallinfo before_ctor = mallinfo();
    auto c = new C;
    struct mallinfo after_ctor = mallinfo();
    auto i = c->i;
    delete c;
    struct mallinfo after_dtor = mallinfo();
    printf("\n--- memory pre-allocated? -------------------- \n\n");
    prnt(before_ctor);
    printf("\n--- memory changed after \"new\" object? ----- \n\n");
    prnt(after_ctor);
    printf("\n--- memory changed after \"delete\" object? --- \n\n");
    prnt(after_dtor);
    printf("\ni = %d\n", i);
}

运行这段代码后,能直观看到进程启动时libc就已经预分配了一块堆空间(arena字段),当执行new C时,只是从这块预分配空间中划出一小部分标记为已使用;执行delete后,这块内存又被标记为空闲,但不会立刻归还给内核——这就是libc内存分配器的"预分配+缓存"策略,目的是减少系统调用的开销。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.07 10:28:02