有没有办法减小 C 语言中线程的堆大小?[关闭]

Is there a way to reduce the heap size of threads in C language? [closed]

提问人:Kay 提问时间:11/1/2023 最后编辑:Kay 更新时间:11/1/2023 访问量:95

问:


编辑问题以包括所需的行为、特定问题或错误以及重现问题所需的最短代码。这将帮助其他人回答这个问题。

18天前关闭。

地块图

我使用 Valgrind 的 Massif 功能来检查我的 C 语言程序的内存使用情况,以调查内存使用情况。 我的代码中有许多动态分配,但根据 Massif 的说法,我发现它始终使用相同数量的内存。 经过进一步调查,我发现我的程序使用两个线程,每个线程一致地分配 64MB 的堆内存。

根据附图,可以观察到,最初创建两个线程时,它们使用了 150.3MB 的内存。当一个线程终止时,精确减少了 64MB,导致内存使用量为 86.3MB。

我不执行动态分配,以证明需要 64MB 的堆内存是合理的。这似乎是一种完全的浪费

用 C 语言创建线程是否必然导致使用固定的 64MB 堆内存?有没有办法减少分配给线程的堆内存?

操作系统: Ubuntu 22.04

我尝试调整堆栈大小,但自然无效。 我想减少分配给线程的 64MB 堆内存。

c pthreads 堆内存

评论

1赞 Lundin 11/1/2023
那么,您使用多少堆内存(如果有)?我们无法真正推测在没有看到代码的情况下占用了 x 字节的代码部分。
0赞 stark 11/1/2023
既然 Linux 是懒惰分配的,你为什么要在乎呢?只有当您实际使用它们时,才会分配它们。每线程存储的最大组件是其堆栈。
1赞 Andrew Henle 11/1/2023
代码会占用大量内存的原因有很多。您尚未演示您的代码如何或为何使用比您想象的更多的内存。没有人可以回答你的问题,并告诉你如何在不知道代码如何使用内存的情况下减少代码的内存使用。创建两个线程本身不会使用总共 128 MB 的 RAM。
0赞 Andrew Henle 11/1/2023
理想情况下,您需要编辑问题并添加尽可能多的代码来演示问题。代码的启动方式和运行环境以及程序使用的资源限制也很重要。该命令将显示运行它的 shell 的软限制,但程序可以在不同的限制下运行。ulimit -a
0赞 Kay 11/1/2023
@stark我稍后将在嵌入式系统中使用它,并且有非常严格的 RAM 使用限制。我很惊讶地看到 Valgrind 报告内存使用过多。根据您所说的,这是否意味着如果 Valgrind 报告 150MB 的内存使用量,它实际上可能没有使用那么多内存?

答:

1赞 Simon Goater 11/1/2023 #1

这里有一个简单的例子,表明并不是创建 pthreads 占用了所有空间。您的线程必须有自己的内存分配与之关联。在这种情况下,如果可能的话,您可能需要重新设计程序以更有效地使用内存。

有了这个程序,我可以轻松创建 10,000+ 个线程,甚至没有 1GB 的内存使用量增加。

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>

// gcc threadmemtest.c -o threadmemtest.bin -O3 -Wall -pthread -march=native

void* sleepforabit(void*arg) {
  sleep(25);
  return NULL;
}

int main(int argc, char **argv){
  int i, numthreads = 5;
  if (argc > 1) numthreads = atoi(argv[1]);  
  pthread_t *threadid = malloc(numthreads*sizeof(pthread_t));
  for (i=0; i<numthreads; i++) {
    if (pthread_create(&threadid[i], NULL, sleepforabit, NULL) != 0) {
      fprintf(stderr, "Error creating pthread[%i].\n", i);
      numthreads = i;
      break;
    }
  }
  for (i=0; i<numthreads; i++) {
    pthread_join(threadid[i], NULL);
  }
  free(threadid);
  pthread_exit(0);
}

评论

0赞 Andrew Henle 11/1/2023
OP 的代码可能会使用 non- 创建线程,并使用 pthread_attr_setstacksize() 设置更大的堆栈大小。这个问题确实需要更多细节。NULLpthread_attr_t
0赞 stark 11/1/2023
请像 OP 一样添加地块总数。
0赞 Andrew Henle 11/1/2023
@stark 那会很有用,但我认为没有必要。x86_64 Linux 上的默认线程堆栈大小仅为 2 MB,这强烈暗示每个线程使用 64 MB 的 OP 代码比默认线程创建要多得多。这些细节需要添加到问题中。
0赞 Kay 11/1/2023
我能够确认线程通过您的代码根据需要分配堆内存,Valgrind 报告的总使用量为 40MB。谢谢。