【发布时间】:2014-07-09 05:37:53
【问题描述】:
先决条件
POSIX.1 2008 specifies setrlimit() 和 getrlimit() 函数。为 resource 参数提供了各种常量,其中一些在下面复制以便更容易理解我的问题。
定义了以下资源:
(...)
RLIMIT_DATA
这是进程的数据段的最大大小,以字节为单位。如果超出此限制,malloc() 函数将失败,并将 errno 设置为 [ENOMEM]。
(...)
RLIMIT_STACK
这是初始线程堆栈的最大大小,以字节为单位。该实现不会自动将堆栈增长到超出此限制。如果超过此限制,则应为线程生成 SIGSEGV。如果线程阻塞 SIGSEGV,或者进程忽略或捕获 SIGSEGV 并且没有安排使用备用堆栈,则 SIGSEGV 的处置应在生成之前设置为 SIG_DFL。
RLIMIT_AS
这是进程总可用内存的最大大小,以字节为单位。如果超出此限制,malloc() 和 mmap() 函数将失败,并且 errno 设置为 [ENOMEM]。此外,自动堆栈增长会因上述影响而失败。
此外,POSIX.1 2008 defines 数据段如下:
3.125 数据段
与进程关联的内存,可以包含动态分配的数据。
我了解RLMIT_DATA 资源传统上用于表示可以通过brk() 函数分配给进程的最大内存量。 POSIX.1 的最新版本不再指定此函数,并且许多操作系统(例如 Mac OS X)不支持将此函数作为系统调用。相反,它使用mmap() 的变体进行模拟,这不是 POSIX.1 2008 的一部分。
问题
我对@987654330@ 资源的语义和使用有点困惑。以下是我的具体问题:
根据本规范,堆栈可以成为数据段的一部分吗?
-
标准中提到
RLIMIT_DATA:“如果超出此限制,malloc() 函数将失败,errno 设置为 [ENOMEM]。”这是否意味着使用malloc()分配的内存必须是数据段的一部分?在 Linux 上,使用
mmap()分配的内存不计入数据段。只有使用brk()或sbrk()分配的内存是数据段的一部分。最新版本的 glibc 使用malloc()实现,它使用mmap()分配其所有内存。因此RLIMIT_DATA的值不会影响您可以通过malloc()的实现分配的内存量。 这是否违反了 POSIX.1 2008?
-
其他平台是否表现出类似的行为?
标准中提到了
RLIMIT_AS:“如果超出此限制,malloc() 和 mmap() 函数将失败,并且将 errno 设置为 [ENOMEM]。”由于mmap()的失败没有为RLIMIT_DATA指定,所以我推断从mmap()获得的内存不计入数据段。 这个假设是真的吗?这是否仅适用于
mmap()的非 POSIX 变体?
【问题讨论】: