Как узнать, сколько свободной памяти осталось в GNU C ++ в Linux - PullRequest
6 голосов
/ 24 декабря 2008

Я пишу программу на C ++ (скомпилированную с gcc и работающую в RedHat Linux). Программа должна знать во время выполнения, сколько места осталось в стеке и сколько осталось в куче. Я понимаю, что не может быть определенного ответа на этот вопрос (о куче), поэтому в качестве альтернативы я мог бы вместо этого использовать объем памяти, уже выделенный из кучи. Есть ли вызов функции библиотеки / системы, который даст мне эти данные?

Я хотел бы добавить, что мне это нужно только для целей отладки, и мне нужны только приблизительные оценки, поэтому быстрые и грязные решения вполне приемлемы. Однако мне нужно очень часто запрашивать использование памяти, так что отсылка утилите командной строки Unix и анализ ее выходных данных недопустимы.

Ответы [ 8 ]

2 голосов
/ 24 декабря 2008

Вы, вероятно, можете создавать свои собственные новые функции и функции удаления, которые инкапсулируют настоящие операторы new и delete и одновременно отмечают использование памяти.

Для стека в C есть хитрость, где вы смотрите на адрес первой локальной переменной, определенной в вашей текущей функции, чтобы получить общее представление о том, где находится указатель стека в данный момент. Я думаю, что это должно работать в C ++, но не пробовал.

1 голос
/ 08 июля 2013

Это функция C, которая возвращает количество свободной памяти на Raspberry PI. Это работает, читая / proc / meminfo. Я не уверен, что это работает для других систем.

#include <stdio.h>
#include <string.h>
// Return the amount of free memory in kbytes.
// Returns -1 if something went wrong.
int getfreememory()
{
  int returnValue;
  const int BUFFER_SIZE = 1000;
  char buffer[BUFFER_SIZE];
  FILE *fInput;
  int loop;
  int len;
  char ch;
  returnValue = -1;
  fInput = fopen("/proc/meminfo","r");
  if (fInput != NULL)
  {
    while (!feof(fInput))
    {
      fgets(buffer,BUFFER_SIZE-1,fInput);
      if (feof(fInput))
      {
        break;
      }
      buffer[BUFFER_SIZE-1] = 0;
      // Look for serial number
      if (strncmp(buffer,"MemFree:",8)==0)
      {
        // Extract mem free from the line.
        for(loop=0;loop<BUFFER_SIZE;loop++)
        {
          ch = buffer[loop];
          if (ch == ':')
          {
             returnValue = 0;
             continue;
          }
          if (ch == 0)
          {
              break;
          }
          if (returnValue >=0)
          {
             if (ch >='A')
             {
                break;
             }
             if ((ch >='0') && (ch <='9'))
             {
                returnValue = returnValue * 10 + (ch-'0');
             }
          }
        }
        break;
      }
    } 
    fclose(fInput);
  }
  return returnValue;
}
1 голос
/ 24 декабря 2008

Имейте в виду, что в 32-битных системах стек растет вниз, а куча растет вверх, и эти два могут встретиться где-то посередине. Следовательно, пространство может быть выделено для стека или кучи, но не для обоих одновременно. Обратите внимание, что сегменты разделяемой памяти (если вы их используете) усложняют карту памяти. Так что можно динамически загружать (совместно использовать) библиотеки.

+------------+
|    stack   | high addresses
|      |     |
|      v     |
+------------+
|            |
|   unused   |
|            |
+------------+
|            |
|      ^     |
|      |     |
|    heap    |
|            |
+------------+
|            |
|     bss    |
|            |
+------------+
|            |
|    data    |
|            |
+------------+
|            |
|    text    |
|            | low addresses
+------------+

В 64-битной системе достаточно адресного пространства, чтобы вы исчерпали реальную и виртуальную память до возникновения коллизий.

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

Скорее всего, вам лучше спросить «осталось ли x МБ (ГБ?) Свободного места», а не «сколько осталось МБ (ГБ?)». Другие люди указывали на файловую систему /proc как на источник информации о том, сколько памяти используется. Я не уверен, достоверно ли он говорит вам о том, сколько памяти доступно для захвата.

1 голос
/ 24 декабря 2008

на Linux вы можете прочитать / proc / pid / status

0 голосов
/ 25 февраля 2009

getrlimit с параметром RLIMIT_STACK скажет вам, сколько всего стекового пространства в общем. С помощью параметра RLIMIT_AS вы можете узнать, сколько там виртуальной памяти.

Для получения дополнительной информации смотрите http://linux.die.net/man/2/getrlimit

0 голосов
/ 24 декабря 2008

Для части кучи, возможно, вы достигли предела ресурса. Проверьте это .

Вы можете использовать Valgrind для профилирования стека, но что вы собираетесь с ним делать? Стек не похож на кучу. Вы говорите, что хотите сделать это в целях отладки. Если ваша программа работает нормально, проблем со стеком нет (по крайней мере, связанных с ее размером).

Вы можете установить размер стека для созданных вами потоков и проверить значение указателя стека, посмотрев адреса локальных переменных (которые не должны быть оптимизированы). Просто сделайте некоторую математику, используя начальный размер, начальное значение указателя стека и текущее значение указателя стека, и вы получите несколько хороших чисел. Только не забудьте сначала узнать направление стека. Это может измениться от платформы к платформе.

Я думаю, что если вы так сильно заботитесь об использовании кучи, то ваша программа, вероятно, утечка памяти. В этом случае Valgrind может указать вам правильное направление. Valgrind

0 голосов
/ 24 декабря 2008

Инструмент массива Valgrind поддерживает как стек, так и кучу профилирование . Вы можете проверить его исходный код, чтобы увидеть, как он это делает.

0 голосов
/ 24 декабря 2008

Вы можете проверить в пространстве имен / proc файлы / proc / / smaps и / proc / / maps, где - текущий идентификатор процесса.

Проверьте этот блог out.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...