如何在Linux中限制C代码的堆大小

4
我想知道在Linux机器上执行的C代码是否可以限制分配的堆大小。
这是否可行?
这样做的目的是我正在动态分配约70KBytes的内存和约20KBytes的堆栈内存,除了其他全局变量和本地变量。动态分配是通过malloc()完成的。
因此,为了确认问题不在堆分配中,我想限制将要运行的C代码的堆内存。
我在线阅读了一些文章,并发现如果使用malloc(),可能会超额承诺内存,但如果使用calloc(),我们将只获得可用内存而没有超额承诺,因为calloc()必须在提供指针之前初始化内存块为零。但由于初始化开销,我不想使用calloc()。

你确定避免微小的calloc开销(仅适用于小对象)是值得的吗?你进行过测量吗?在Linux上,大内存区域通常通过mmap进行malloc分配,这将提供零填充内存! - Basile Starynkevitch
你真正苦恼的问题是什么?请编辑你的问题以改善它! - Basile Starynkevitch
嗨,Basile,谢谢你的回复。我正在一个嵌入式平台上使用C代码,但是出现了崩溃。这个崩溃看起来像是内存问题或者地址错误。这就是我想要限制我的C代码堆内存并在PC平台上进行调试的原因。 - sunny
2个回答

4
您可以在程序中使用setrlimit(2),可能需要使用RLIMIT_AS(正如Ouah's answer所述)。

更好的方法是让您的shell来处理。使用bash内置的ulimit命令即可。

确保您的程序在任何地方都正确且完整地处理了malloc失败(测试每个malloc返回值是否为NULL,表示其失败)。

如果您不测试malloc的结果,当它失败时,它会返回NULL,接下来的指令很可能会解引用空指针(或某个非常靠近它的地址),这是未定义行为,在Linux上会导致段错误

您可能应该考虑在调试阶段使用valgrind

顺便说一下,70Kilobytes的内存在今天已经算很小了(至少在Linux笔记本电脑、台式机甚至平板电脑上是这样)。请注意,C标准库可能会在底层调用malloc(例如,fopen返回一个FILE句柄,其中有一些缓冲区,可能是通过malloc内部获取的)。

并且可以使用以下命令在Linux上禁用内存超额提交

echo 0 > /proc/sys/vm/overcommit_memory

需要以root身份运行。


你应该输出1来禁用过度承诺,而不是0。 - Chen Li

1
在 POSIX 系统上,您可以使用 setrlimit 函数来限制进程的虚拟内存大小。
从 POSIX 文档 中得知:

RLIMIT_AS

这是进程可用总内存的最大值(以字节为单位)。如果超过此限制,则 malloc() 和 mmap() 函数将失败,并将 errno 设置为 [ENOMEM]。此外,自动堆栈增长也会出现上述影响。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接