【问题标题】:C - How much memory can a program allocate for itself - and how is it determined?C - 程序可以为自己分配多少内存 - 它是如何确定的?
【发布时间】:2013-09-15 23:36:14
【问题描述】:

可以从程序分配的内存量是否有限制?我的意思是,对于程序是否有任何保护措施,例如,在无限循环中分配内存?

malloc() 的调用何时会返回 NULL 指针?

【问题讨论】:

  • 这取决于您的操作系统。
  • 当您考虑按需分页操作系统时,这个讨论变得更加复杂;只要您不向新分配的内存写入任何内容,它就没有完全分配。这意味着您可以在只有 32 MiB RAM 的系统上分配 2 GiB 的内存,malloc (...) 将立即返回……当您第一次读/写该内存时,内核最终进行了真正的分配。这就是为什么malloc (...) 的失败更能说明地址空间不足而不是实际存储空间不足。不用说实时操作系统不使用按需分页:)

标签: c memory


【解决方案1】:

我正在反向解决这个问题。 请参阅pointer 存储内存块的地址。如果我们能够找到它可以存储的最大地址,那么我们就可以找到分配给我们程序的内存。

代码

#include <stdio.h>

int main()
{

    void *p;
    printf("%zu",sizeof(p));
    return 0;
}

输出

8

理解:

pointer size is 8 bytes.
8 bytes -> 64 bits
Max address it can store/ last memory block address: 2^64-1
Memory block addresses: 0, 1, 2, 3, ... 2^64-1
Memory allocated to program: 2^64 byte

【讨论】:

  • 您更多地指的是 64 位指针的 可寻址空间,这并不能完全回答这里的原始问题。但否则你是正确的,如果你在一个可以满足 64GB 内存请求的系统上,一个 64 位指针将包含 2^64 - 1 的值。尽管在现代操作系统上这种情况存在许多问题,但至少 64GB 内存是一个巨大的价值
  • @sherrellbc 看到当我们在C++ 中编写代码时,我们只是在编译时写成文本,然后为它的目标代码分配内存。所以这就是你说的记忆对吗?如果我们在编写代码时增加内存中的变量,那么分配给目标代码的内存也会增加。然后我们检查上限,因为指针大小为8 字节,它可以指向2^64-1 空间意味着这是最大内存量,但这是理论上的,我知道通常我们有RAM 大约16 GB 意味着2^34-1 最大地址。这是我的想法,如果我错了,请纠正我。
【解决方案2】:

是的,有一个限制。该限制取决于许多因素,包括(但不限于):

  • 程序的指令集(例如,32 位二进制文​​件的地址空间比 64 位二进制文​​件小)。
  • 系统有多少可用内存。 (这里的“内存”包括虚拟内存。)
  • 系统管理员或特权进程设置的任何人为限制(例如,参见setrlimit() 和(过时的)ulimit() 函数)。

当内存无法分配时,malloc() 将返回NULL。如果系统完全内存不足,您的进程可能会被强制终止。

【讨论】:

  • +1 用于提及 setrlimit()。另请参阅 ulimit(我在 AIX 上工作了 4 年,在 Debian Linux 下工作了 2 年——这两者都人为地降低了默认值,这是我存在的祸根)。
  • @PaulProgrammer 忘记了 ulimit,感谢您指出这一点。将其添加到我的答案中。
【解决方案3】:

来自Wikipedia

malloc 可以分配的最大内存块取决于 主机系统,特别是物理内存的大小和 操作系统实现。理论上最大数 应该是size_t 类型中可以保存的最大值,即 是一个与实现相关的无符号整数,表示大小 的内存区域。最大值为 2CHAR_BIT × sizeof(size_t) − 1,或 C99 标准中的常量 SIZE_MAX

【讨论】:

  • 这是有用的信息,但是是关于malloc() 可以满足的最大single 分配请求。问题似乎是关于许多分配总和的限制。
  • @Jacob CHAR_BIT 是什么? Clion 说它是未声明的标识符?还是你的意思是sizeof(char)
  • @cdhowie 我认为这也只分配给程序的内存,不是吗?这就是问题中提出的问题。
【解决方案4】:

这取决于操作系统和标准库。

在 Linux 上,

  • 当地址空间用完时,malloc() 将返回NULL

  • 当您用完物理内存和交换空间时,OOM 杀手将运行并终止一个进程以释放内存。

【讨论】:

  • 即使有足够的地址空间,GNU malloc(通常在 linux 上使用)是否也对单个调用有最大限制?
  • 如果你通过 glibc 挖掘,应该很容易找到。
  • 对我的系统进行了测试(linux 5.4.72-gentoo、glibc-2.32、x86_64)。 malloc 的上限似乎为 8012111176 字节,或十六进制的 0x1dd8f1d48。
  • @HAL9000:这是 glibc 限制还是 mmap 限制?
  • 不知道,我只是想看看malloc使用二分法是否有上限。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-03-02
  • 2020-03-12
  • 1970-01-01
  • 2011-07-27
  • 2011-08-27
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多