分叉故障:无法分配内存

4
我在一台Linux机器上运行一个程序。它分叉一个进程来发送邮件,并经常记录无法分叉的失败消息,标明无法分配内存。
当我检查驻留内存的大小时,它大约为12Gb(此机器配置的交换空间仅为1Gb)。
有没有办法确保这个巨大的内存块不是泄漏,而只是内存增长?
此外,是否有可以调整的系统限制,以便我不会遇到任何分叉失败?

1
你想说这个进程已经占用了12GB的内存?这台机器提供多少内存?这台机器上设置了什么内存限制? - alk
我的意思是使用 TOP 命令中显示的 RES。这里的系统具有 32Gb 的内存,而 ulimit 中的最大内存大小则显示为无限制。 - wabbit
2个回答

3

为了检查内存泄漏,您可能想在Valgrind下运行程序:http://valgrind.org


要从控制台/ shell 获取/设置限制,可以使用ulimit命令。

从程序内部,系统调用getrlimit()/setrlimit()提供此功能。


在可能由于fork()导致内存紧张的情况下,另一种解决方法是使用vfork(),然后立即调用exec*()函数族的成员之一。

来自man vfork

vfork()clone(2)的一个特例。它用于创建新进程,而不复制父进程的页表。在性能敏感的应用程序中可能会有用,其中创建一个子进程,该子进程随即发出execve(2)

vfork()fork(2)不同,因为父进程被挂起,直到子进程终止(通常是通过调用_exit(2)或异常地,在传递致命信号后),或者它调用execve(2)。在那之前,子进程与其父进程共享所有内存,包括堆栈。子进程不能从当前函数返回或调用exit(3),但可以调用_exit(2)


这是有信息价值的。valgrind没有显示任何重大泄漏,所以我猜测它是内存增长造成的。我无法更改程序来设置资源限制,可以在系统级别上使用ulimit或类似的东西来完成吗? vfork()看起来是一种合适的解决方案,但这又需要代码更改。 - wabbit
1
请查看 man bash 以获取有关 ulimit 的详细说明。 - alk

1

我刚刚在一个嵌入式系统上遇到了这个问题。没有设置限制,还有足够的空闲RAM来运行一个小的df进程,所以这让我感到困惑。然后我记起了fork()是通过写时复制来工作的 - 所以子进程可能会在不久的将来需要与父进程一样多的RAM。如果你看到机器上似乎有很多空闲RAM,那么请记住:它是否至少与调用fork()的进程使用的RAM一样多?


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