先决条件
POSIX.1 2008 http://pubs.opengroup.org/onlinepubs/9699919799/ 指定 http://pubs.opengroup.org/onlinepubs/9699919799/functions/setrlimit.html the setrlimit()
and getrlimit()
功能。提供了各种常数resource
论点,其中一些内容转载如下,以便更容易理解我的问题。
定义了以下资源:
(...)
RLIMIT_数据
这是进程数据段的最大大小,以字节为单位。如果超过此限制,malloc() 函数将失败,并将 errno 设置为 [ENOMEM]。
(...)
RLIMIT_STACK
这是初始线程堆栈的最大大小(以字节为单位)。该实现不会自动将堆栈增长到超出此限制。如果超过此限制,将为线程生成 SIGSEGV。如果线程正在阻塞 SIGSEGV,或者进程正在忽略或捕获 SIGSEGV 并且尚未安排使用备用堆栈,则 SIGSEGV 的处置应在生成之前设置为 SIG_DFL。
RLIMIT_AS
这是进程的总可用内存的最大大小(以字节为单位)。如果超过此限制,malloc() 和 mmap() 函数将失败,并将 errno 设置为 [ENOMEM]。此外,自动堆栈增长会因上述影响而失败。
此外,POSIX.1 2008defines http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap03.html#tag_03_125 数据段像这样:
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()
or sbrk()
是数据段的一部分。最新版本的 glibc 使用malloc()
分配其所有内存的实现mmap()
。的价值RLIMIT_DATA
因此对您可以使用此实现分配的内存量没有影响malloc()
.
这是否违反了 POSIX.1 2008?
-
其他平台是否也表现出类似的行为?
该标准说的是RLIMIT_AS
:“如果超过此限制,则 malloc() 和 mmap() 函数将失败,并将 errno 设置为 [ENOMEM]。”由于失败mmap()
没有指定用于RLIMIT_DATA
,我得出结论,记忆是从mmap()
不计入数据段。
这个假设是真的吗?这是否仅适用于非 POSIX 变体mmap()
?
FreeBSD 还存在在默认 malloc 实现中使用 mmap(2) 实现 malloc(3) 的问题。我在将产品从 FreeBSD 6 移植到 7 时遇到了这个问题,也就是发生了切换。我们将每个进程的默认限制从 RLIMIT_DATA=512M 更改为 RLIMIT_VMEM=512M,即将虚拟内存分配限制为 512MB。
至于这是否违反POSIX,我不知道。我的直觉是,很多东西都违反了 POSIX,而 100% 符合 POSIX 的系统就像严格确认的 C 编译器一样罕见。
编辑:呵呵,现在我发现 FreeBSD 的名称 RLIMIT_VMEM 是非标准的;他们将 RLIMIT_AS 定义为 RLIMIT_VMEM 以实现 POSIX 兼容性。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)