C:堆、Macos 和 Linux 上的大 GB 数组

问题描述 投票:0回答:1

我正在 64GB Mac Studio 上工作,但也尝试了 Linux 下的代码。所有均为截至 2023 年 11 月的最新版本,macos 上为 clang 15.0.0。 Linux 上的 gcc 12.3.0。

ulimit
告诉我,除了堆栈大小、进程和文件描述符之外,我们是不受限制的。)

我在 C 中处理very大型数组时遇到麻烦,声明为

static
以避免堆栈。在Macos上,我什至无法分配1GB。在 Linux 上,我不能超过 11GB。 (是的,我确实有这么大的数据集。考虑到台式计算机现在可以有 256GB 或更多,我本以为 C 基础将被设置为默认处理这么多 RAM。)

可以可靠地生成此错误(减少)的基本代码如下。现在人们如何处理这个问题?

代码

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>

#define SSS 2025L  // at 2025, this dies on macos
#define MB (1024*1024L)
#define DIM (SSS*MB)

static uint8_t storagearray[DIM];


int main(int argc, char *argv[]) {

  memset( storagearray, 1, sizeof storagearray );
  fprintf(stderr, "[clear ok on %ld = %ld B = %ld MB]\n",
      DIM, sizeof(storagearray), sizeof(storagearray)/1024/1024);

  long int sum=0;
  for (long ix=0; ix < DIM; ++ix) sum+= storagearray[ix];

  fprintf(stderr, "[write ok %ld, exit]\n", sum);

  return 0;
}

Mac系统

当 SSS 为 2025L 或更高时,它会因以下两个错误之一而使 maos 不及格:

  1. 总线错误(或使用 -fsanitize=address,违规)

  2. 调用时(不是运行一段时间后)

  dyld[99042]: dyld cache '(null)' not loaded: syscall to map cache into shared region failed
  dyld[99042]: Library not loaded: /usr/lib/libSystem.B.dylib
    Referenced from: <BB88C06F-4A2F-3CCB-8270-8A6D2E5DC717> /Users/ivo/Sync/research/country-climate-data-gridded/econ-activity/nightlites/data/a.out
  Reason: tried: '/usr/lib/libSystem.B.dylib' (no such file), '/System/Volumes/Preboot/Cryptexes/OS/usr/lib/libSystem.B.dylib' (no such file), '/usr/lib/libSystem.B.dylib' (no such file, no dyld cache)

Linux

当SSS为12,000时,它会显示“已杀”。当它达到 15,000 时,它会显示“segfault”。

c memory out-of-memory
1个回答
0
投票

ulimit
告诉我我们是无限的,除了 堆栈大小、进程和文件描述符。)

“无限”不应按字面意思理解。这意味着操作系统不会对给定的资源类型施加任何“额外”限制,但操作系统和 C 实现中仍然存在内置限制,最终您会受到机器硬件的限制。

我在 C 中处理非常大的数组时遇到麻烦,将其声明为静态 避免堆栈。

在文件范围声明数组足以为其提供静态存储持续时间。另外声明它
static

不会对它的存储位置产生进一步的影响,至少就 C 语言而言是这样。 (在函数内部声明的变量则不然。)


在macOS上,我什至无法分配1GB。在Linux上,我 不能超过11GB。

这是操作系统和 C 实现的函数。没有什么要求您的 C 实现能够支持任意大的声明对象。

现在人们如何处理这个问题?

这又是操作系统和 C 实现的一个功能,但通常您可以动态分配比静态或(尤其是)自动分配的对象更大的对象。如果您无法静态分配足够大的对象,那么动态分配(
malloc

calloc
)是您最好的选择。
    

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