Как узнать, сколько свободной памяти осталось в GNU C++ в Linux

StackOverflow https://stackoverflow.com/questions/391107

  •  23-08-2019
  •  | 
  •  

Вопрос

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

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

Нет правильного решения

Другие советы

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

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

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

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

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

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

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

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

Это функция 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;
}

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

Проверять этот пост в блоге вне.

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

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

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

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

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

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

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top