C语言中只读内存与堆内存占用对比及大文件场景疑问
XML解析内存占用问题
我们定义如下NODE结构体:
typedef struct tNODE { struct tNODE* parent; char* inner_text; }NODE;
存在两种inner_text的初始化方式:
- 只读内存初始化:
NODE* temp = new_node(parent); temp->inner_text = "something";
- 堆内存初始化:
NODE* temp = new_node(parent); temp->inner_text = strdup("something");
我正在解析一个超过3GB的大型XML文件,通过Valgrind发现使用只读内存初始化时,堆总占用比堆内存初始化更低。请问:
- 该现象是否始终成立?
- 原因是什么?
- 处理大文件时是否需要考虑这一点?
问题解答
1. 该现象是否始终成立?
是,只要两种方式处理的是相同的文本内容,只读内存初始化的堆占用必然更低。
2. 原因分析
- 只读内存初始化里的
"something"是字符串字面量,它存储在程序的只读数据段(.rodata),不属于堆内存范畴,堆里仅需存储NODE结构体本身的内存。 - 堆内存初始化使用
strdup时,该函数会调用malloc在堆上分配一块内存,再将字符串字面量的内容复制进去。此时堆中不仅有NODE结构体,还要加上复制后的字符串内存,堆占用自然更高。 - 若XML中存在大量重复文本,只读内存方式还能自动复用同一个字符串字面量的内存(编译器会自动合并相同的字符串字面量),进一步降低内存开销;而堆内存方式每次调用
strdup都会分配新的堆内存,重复内容会造成大量冗余。
3. 处理大文件时是否需要考虑这一点?
非常有必要,尤其是处理3GB这种超大型XML文件:
- 直接降低堆内存占用,减少内存溢出风险,避免程序因内存不足崩溃。
- 减少堆内存分配和释放的次数,降低内存碎片产生的概率,提升程序运行效率,减少内存管理的开销。
- 但要注意前提:如果解析过程中需要修改
inner_text的内容,就不能用只读内存方式——字符串字面量是只读的,修改会触发未定义行为。只有当inner_text全程作为只读数据使用时,这种方式才安全可行。
内容的提问来源于stack exchange,提问作者Ali
相关产品推荐
相关产品推荐

