先决条件
POSIX.1 2008 指定了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定义的 数据段如下:
3.125 数据段
与进程关联的内存,可以包含动态分配的数据。
我了解该RLMIT_DATA
资源传统上用于表示可以分配给具有该brk()
功能的进程的最大内存量。POSIX.1 的最新版本不再指定此函数,并且许多操作系统(例如 Mac OS X)不支持将此函数作为系统调用。mmap()
相反,它使用不属于 POSIX.1 2008的变体进行模拟。
问题
我对资源的语义和使用有点困惑RLIMIT_DATA
。以下是我的具体问题:
根据此规范,堆栈可以成为数据段的一部分吗?
该标准说
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()
不计入数据段。这个假设是真的吗?这是否仅适用于 的非 POSIX 变体
mmap()
?