UNIX、Linux和Windows的进程内存限制和地址空间

4

UNIX,Linux和Windows的单个进程最大内存量是多少?如何计算?有了4 GB RAM,用户地址空间和内核地址空间各是多少?

3个回答

7

4GB内存的用户地址空间和内核地址空间各为多少?

一个进程的地址空间分为两部分,

用户空间:在标准32位x86_64体系结构中,可寻址内存最大为4GB,其中地址从0x000000000xbfffffff = (3GB)用于代码、数据段。当用户进程在用户或内核模式下执行时,可以寻址此区域。

内核空间:同样,地址从0xc00000000xffffffff = (1GB)用于内核的虚拟地址空间,只有在进程以内核模式执行时才能寻址。

这个特定的地址空间在x86上的分割是由PAGE_OFFSET的值决定的。参考Linux 3.11.1v page_32_types.hpage_64_types.h,页面偏移如下所示, #define __PAGE_OFFSET _AC(CONFIG_PAGE_OFFSET, UL) 其中Kconfig定义了默认值default 0xC0000000以及其他可用的地址拆分选项。
同样地,在64位系统中, #define __PAGE_OFFSET _AC(0xffff880000000000, UL)
在64位体系结构中,由于巨大的地址空间,3G/1G的分割不再适用。根据来源,最新的Linux版本已经给出了上述偏移量作为偏移量。
当我看到我的64位x86_64架构时,32位进程可以拥有整个4GB的用户地址空间,而内核将持有4GB以上的地址范围。有趣的是,在现代64位x86_64 CPU上,并非所有地址线都启用(或地址总线不够大),无法提供我们2^64=16 exabytes的虚拟地址空间。也许AMD64/x86体系结构分别启用了48/42个低位,导致地址空间为2^48=256TB/2^42=4TB。现在这肯定会提高具有大量RAM的性能,同时也引发了如何有效管理操作系统限制的问题。

2
在Linux中,有一种方法可以找出您可以拥有的地址空间限制。 使用rlimit结构。
struct rlimit {
    rlim_t cur;    //current limit
    rlim_t max;    //ceiling for cur.
}

rlim_t是无符号长整型。

你可以有类似这样的内容:

#include <stdio.h>
#include <stdlib.h>
#include <sys/resource.h>

//Bytes To GigaBytes
static inline unsigned long btogb(unsigned long bytes) {
    return bytes / (1024 * 1024 * 1024);
}

//Bytes To ExaBytes
static inline double btoeb(double bytes) {
    return bytes / (1024.00 * 1024.00 * 1024.00 * 1024.00 * 1024.00 * 1024.00);
}

int main() {

    printf("\n");

    struct rlimit rlim_addr_space;
    rlim_t addr_space;

    /*
    * Here we call to getrlimit(), with RLIMIT_AS (Address Space) and
    * a pointer to our instance of rlimit struct.
    */
    int retval = getrlimit(RLIMIT_AS, &rlim_addr_space);
    // Get limit returns 0 if succeded, let's check that.
    if(!retval) {
        addr_space = rlim_addr_space.rlim_cur;
        fprintf(stdout, "Current address_space: %lu Bytes, or %lu GB, or %f EB\n", addr_space, btogb(addr_space), btoeb((double)addr_space));
    } else {
        fprintf(stderr, "Coundn\'t get address space current limit.");
        return 1;
    }

    return 0;
}

我在我的计算机上运行了这个程序,结果是:当前的地址空间为18446744073709551615字节,或者17179869183 GB,或者16.000000 EB。

在我的Linux x86_64系统中,最大可用地址空间为16 ExaBytes。

这里是getrlimit()的定义,它还列出了其他你可以传递给getrlimits()的常量,并介绍了getrlimit()的姐妹函数setrlimit()。当rlimitmax成员变得非常重要时,你应该始终检查自己是否超过了这个值,以免内核打你的脸、喝你的咖啡和偷你的文件。

附注:请原谅我的糟糕的鼓点表演 ^_^


1
在Linux系统中,查看man ulimit。它说:ulimit内置用于设置shell和由其生成的任何进程的资源使用限制。如果省略了新的限制值,则打印出该资源限制的当前值。使用“ulimit -a”带有开关选项来打印所有当前值,其他开关(例如“ulimit -n”)打印最大打开文件数。不幸的是,“最大内存大小”显示为“无限制”,这意味着它不受系统管理员的限制。您可以通过以下方式查看内存大小:
cat /proc/meminfo

Which results something like:

MemTotal:        4048744 kB
MemFree:          465504 kB
Buffers:          316192 kB
Cached:          1306740 kB
SwapCached:          508 kB
Active:          1744884 kB
(...)

因此,如果ulimit显示为“无限制”,那么MemFree就全部归你了。几乎是这样。

不要忘记malloc()(以及调用malloc()new运算符)是一个STDLIB函数,因此如果您调用malloc(100) 10次,会有很多“浪费空间”,请点击链接了解原因。


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