Стек и куча пространства для современных компьютеров

При написании на C, как я могу узнать, сколько места в стеке доступно в памяти, когда я запускаю программу? Как насчет места в куче?

Как узнать, сколько памяти используется во время выполнения моей программы?


person dvanaria    schedule 25.09.2010    source источник
comment
Вот некоторая информация о размерах стека в системах Windows msdn. microsoft.com/en-us/library/ms686774%28VS.85%29.aspx   -  person Maciej Hehl    schedule 25.09.2010


Ответы (3)


Это все специфично для Win32 (не совсем для C, все просто API ОС):

Когда поток создается, он по умолчанию получает 1 МБ пространства в стеке, что может быть изменено в любом API CreateThread, который вы используете.

Вы можете заглянуть в блок информации о потоке, чтобы найти фактическую информацию о стеке, но, несмотря на то, что это задокументировано, этот метод официально не поддерживается, см. http://en.wikipedia.org/wiki/Win32_Thread_Information_Block .

Кроме того, для 32-разрядного приложения вы можете адресовать только до 2 ГБ, поэтому для приложения, которое по своей природе использует много памяти, нужно следить за общим размером виртуального адресного пространства процесса (выделено + зарезервировано), который включает в себя все выделения кучи. Вы можете программно получить доступ к виртуальной памяти процесса с помощью API GlobalMemoryStatusEx, см. ullTotalVirtual параметр для виртуального адресного пространства. Как только ваш процесс приближается к 1,8 или 1,9 ГБ VAS, выделение кучи и вызовы VirtualAlloc начинают давать сбой. Для «обычных» приложений вам не нужно беспокоиться о том, что VAS закончится, но всегда полезно проверить наличие неудачных распределений. Кроме того, у вас не должно быть переполнения стека, если у вас нет ошибки или плохого дизайна.

person Chris O    schedule 25.09.2010
comment
Это было очень полезно, спасибо. Это дает мне отправную точку. - person dvanaria; 27.09.2010

Существует философия, согласно которой, когда вам нужно задавать такого рода вопросы по практическим, а не по образовательным или информационным причинам, вы делаете что-то серьезно неправильное.

Если вы запрашиваете это для проверки ошибок или для того, чтобы убедиться, что вашей программе достаточно памяти и т. д., то не беспокойтесь об этом, серьезно. Что касается памяти ваших программ, вы можете использовать диспетчер задач (в Windows), если это только для отладки. Если вам нужно знать это в своей программе, я бы не стал рассчитывать на какое-либо нехакерское решение.

person Alexander Rafferty    schedule 25.09.2010
comment
Ха, спасибо за ваш ответ. Это чисто из воспитательных соображений. Я написал так много программ на C и имею смутное представление о стоимости/использовании пространства памяти, но мне было интересно, как профессиональные разработчики получают конкретное представление о том, как их программы влияют на систему. - person dvanaria; 25.09.2010
comment
Еще одна философия заключается в том, что если вашей программе нужна память, она должна просто попытаться выделить ее и быть готовой к сбою. Быть разумным в отношении того, что вы выделяете, всегда является хорошей практикой. Если вам не вручили требование, согласно которому вы не можете выделить больше x объема памяти, последствия, которые это оказывает на остальную часть системы, на самом деле являются проблемой системной инженерии. Кроме того, не думайте, что цифра фиксирована. Ваша программа может работать в операционной системе, предназначенной для завершения процессов с более низким приоритетом для освобождения памяти, когда процесс с более высоким приоритетом достигает потолка. - person Blrfl; 25.09.2010

Абстракции по какой-то причине На самом деле, ваша программа не должна беспокоить это. Это проблема ОС, ваша проблема должна быть эффективной с тем, что ей нужно, и позволить ОС выполнять свою работу.

Если вы настаиваете, вы можете изучить /proc/meminfo, brk(), getrlimit() и setrlimit() (вот некоторые docs) со значениями RLIMIT_STACK и RLIMIT_DATA для приблизительных и приблизительных значений.

#include <sys/resource.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>

int main (int argc, char *argv[])
{
  struct rlimit limit;

  /* Get the stack limit. */
  if (getrlimit(RLIMIT_STACK, &limit) != 0) {
    printf("getrlimit() failed with errno=%d\n", errno);
    exit(1);
  }

  printf("The stack soft limit is %llu\n", limit.rlim_cur);
  printf("The stack hard limit is %llu\n", limit.rlim_max);
  exit(0);
}

Изменено из здесь см. man getrlimit в вашей системе

Если вы укажете, что и почему вы хотите это сделать, возможно, у кого-то есть лучший метод или способ сделать то, что вы хотите.

person Aiden Bell    schedule 25.09.2010