处理UNIX,Linux和Windows的内存限制和地址空间

问题描述 投票:3回答:3

UNIX,Linux和Windows中单个进程的最大内存量是多少?怎么计算? 4 GB RAM的用户地址空间和内核地址空间是多少?

memory memory-management process operating-system
3个回答
6
投票

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

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

用户空间:在标准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 split由于巨大的地址空间而不再存在。根据源代码,最新的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的性能,同时出现了如何通过操作系统限制有效管理它的问题。


1
投票

在Linux系统上,请参阅man ulimit

(更新)

它说:

ulimit builtin用于设置shell的资源使用限制以及由它生成的任何进程。如果省略新的限制值,则打印资源限制的当前值。

ulimit -a打印出所有当前值,包括开关选项,其他开关,例如ulimit -n打印出来没有。最大打开文件。

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

您可以通过查看内存大小

cat /proc/meminfo

结果如下:

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

所以,如果ulimit说“无限”,那么MemFree就是你的全部。几乎。

不要忘记malloc()(和new运算符,它调用malloc())是一个STDLIB函数,所以如果你调用malloc(100)10次,there will be lot of "slack",请按照链接来了解原因。


1
投票

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

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

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

我在电脑上运行了这个... ... prrrrrrrrrrrrrrrr tsk!

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

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

这里是getrlimit()'s definition它还列出了你可以传递给getrlimits()的其他常数,并介绍了getrlimit()s姐妹setrlimit()。当maxrlimit成员变得非常重要时,你应该总是检查你不要超过这个值,所以内核不会打你的脸,喝咖啡和偷你的文件。

PD:请原谅我的抱歉借口^ _ ^

© www.soinside.com 2019 - 2024. All rights reserved.