3

UNIX、Linux 和 windows 中单个进程的最大内存量是多少?如何计算?4 GB RAM 需要多少用户地址空间和内核地址空间?

4

3 回答 3

7

How much user address space and kernel address space for 4 GB of RAM?

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

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

内核空间:同样,从0xc0000000to 0xffffffff=(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/ x86architectures 分别启用了48/42低位,从而导致2^48= 256TB/ 2^42=4TB地址空间。现在,这无疑提高了大量 RAM 的性能,同时出现了如何在操作系统限制下有效管理它的问题。

于 2013-09-26T12:30:33.113 回答
2

在 Linux 中,有一种方法可以找出您可以拥有的地址空间的限制。使用rlimit结构。

struct rlimit {
    rlim_t cur;    //current limit
    rlim_t max;    //ceiling for cur.
}

rlim_t是一种unsigned long类型。

你可以有类似的东西:

#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;
}

我在我的电脑上运行了这个,然后...... prrrrrrrrrrrrrrrrr tsk!

输出: Current address_space: 18446744073709551615 Bytes, or 17179869183 GB, or 16.000000 EB

我的 Linux x86_64 上有 16 ExaBytes 的最大可用地址空间。

这是getrlimit() 的定义 ,它还列出了您可以传递给的其他常量getrlimits()并引入了getrlimit()sister setrlimit()。当max成员rlimit变得非常重要时,你应该经常检查你没有超过这个值,这样内核就不会打你的脸、喝你的咖啡和偷你的文件。

PD:请原谅我打鼓的抱歉^_^

于 2018-03-09T09:15:13.837 回答
1

在 Linux 系统上,请参见man ulimit

(更新)

它说:

ulimit 内置函数用于设置 shell 和由它产生的任何进程的资源使用限制。如果省略新的限制值,则打印资源限制的当前值。

ulimit -a打印出所有带有开关选项的当前值,其他开关,例如ulimit -n打印出 no。最大。打开文件。

不幸的是,“最大内存大小”告诉“无限”,这意味着它不受系统管理员的限制。

您可以通过以下方式查看内存大小

cat /proc/meminfo

结果类似于:

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 次,会有很多“slack”,点击链接了解原因。

于 2013-09-25T13:38:02.510 回答