运行进程的内存大小是否受OS限制?

时间:2014-07-11 15:23:15

标签: c linux memory operating-system

我根据书籍Programming Pearls编写了一个外部排序程序,最大的数组是char all_nums[10,000,000];,它需要10M堆栈内存(不是很大)。但是这个程序运行不好(我使用clang3.5和gcc4.8编译它并在Ubuntu 14.04运行它),它得到segmentation fault (core dumped)错误。但是当我将数组的大小减小到char all_nums[1,000,000];时,它运行良好。整个代码都在这里https://gist.github.com/xuefu/9aecc7f2b8ae3ab0ce55

  1. 操作系统可以限制运行进程的内存吗?与堆栈内存和堆内存相同吗?
  2. 如何摆脱这种记忆限制?
  3. 如何在C中存储位,如C ++中的类bitset
  4. 主要的排序代码是函数disk_sort()

    void disk_sort()
    {
      char all_nums[MAX_SCOPE]; 
      char buf[MAX_BUF];
      char *ch;
      FILE *fp;
      int n, j;
    
      fp = fopen(FILE_NAME, "r");
    
      for(n = 0; n < MAX_SCOPE-1; ++n)
      {
        all_nums[n] = '0';
      }
    
      all_nums[MAX_SCOPE-1] = '\0';
    
      while(fgets(buf, MAX_BUF, fp) != NULL)
      {
        sscanf(buf, "%d\n", &n);
        all_nums[n]++;
      }
    
      fclose(fp);
      fp = fopen(FILE_RESULT, "a");
    
      n = 0;
      while(all_nums[n] != '\0')
      {
        if(all_nums[n] != '0')
        {
          ch = itostr(n, &j);
          ch[j++] = '\n';
          ch[j] = '\0';
          for(int i = 0; i < all_nums[n] - '0'; ++i)
          {
            fwrite(ch, sizeof(char), j, fp);
          }
          free(ch);
          ch = NULL;
        }
        ++n;
      }
      fclose(fp);
    }
    

2 个答案:

答案 0 :(得分:3)

使用ulimit命令可以获得当前设置的最大堆栈大小属性。

/sujith>ulimit -a
core file size          (blocks, -c) unlimited
data seg size           (kbytes, -d) unlimited
scheduling priority             (-e) 0
file size               (blocks, -f) unlimited
pending signals                 (-i) 192070
max locked memory       (kbytes, -l) 1024000
max memory size         (kbytes, -m) 20907448
open files                      (-n) 1024
pipe size            (512 bytes, -p) 8
POSIX message queues     (bytes, -q) 819200
real-time priority              (-r) 0
stack size              (kbytes, -s) 1024
cpu time               (seconds, -t) unlimited
max user processes              (-u) 192070
virtual memory          (kbytes, -v) 48826320
file locks                      (-x) unlimited

如何不分配创建大于该值的堆栈变量。

修复:

您可以通过以下命令增加堆栈大小。

ulimit -s <size>
ulimit -s unlimited

Increase stack size in Linux with setrlimit

答案 1 :(得分:2)

这可能是一个非常长的答案,所以我会尽量缩短并提供更深入的材料链接。

简而言之: 您没有足够的堆栈内存来分配大的数组 要存储大的东西,你可能应该使用

的内容在堆上分配它
char *all_nums = new char[MAX_SCOPE];

或更好

std::shared_ptr<char> = std::make_shared<char>(MAX_SCOPE);

要调整堆栈大小,请查看此问题:Change stack size for a C++ application in Linux during compilation with GNU compiler因为它提供了几种完成任务的方法,具体取决于您的工具链。

长期:

操作系统可以限制进程的内存使用量,管理员也可以为用户配置限制(在两种情况下都可以参见ulimit for * nix)。总的来说,每个进程都会受到可以处理多少内存的限制,这与操作系统处理虚拟内存的方式有关(参见http://en.wikipedia.org/wiki/Virtual_address_space)。这不是具体问题。

查看代码示例和问题,首先必须区分堆栈和堆内存。这里有更长的解释:http://www.learncpp.com/cpp-tutorial/79-the-stack-and-the-heap/ 通常,堆用于存储可能不适合堆栈但不受管理的较大变量(在c ++的情况下),并且您将使用new或malloc(或其他)来分配堆内存。堆栈内存用于短期本地存储(示例中的数组位于堆栈中)。堆栈内存的大小更受限制,并在声明变量时分配,并在范围结束时自动释放。

希望这有帮助!