Серия Performance Programming: управление памятью (часть 2)

Теперь, когда мы знаем, как организована память в программах на C из нашего последнего блога.

Позвольте мне перечислить несколько распространенных сценариев, свидетельствующих о плохом управлении памятью во время кодирования.

  • Недопустимый доступ к памяти. Эта ошибка возникает, когда инструкция чтения или записи ссылается на нераспределенную или освобожденную память.
  • Утечка памяти. Утечки памяти происходят, когда память выделяется, но не освобождается. Вероятно, он даже не появится сразу, и может пройти несколько дней, прежде чем он появится и приведет к сбою программы.
  • Ошибки сегментации. Ошибки сегментации вызваны попыткой программы прочитать или записать недопустимую ячейку памяти.
  • Неинициализированный доступ к памяти: этот тип ошибки памяти возникает, когда в вашем приложении считывается неинициализированная переменная.
  • Исключение переполнения стека. Исключение, возникающее при переполнении стека выполнения из-за того, что он содержит слишком много вызовов вложенных методов.

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

Вот несколько вещей, которые вы можете сделать, чтобы предотвратить или смягчить ошибки памяти:

  1. Ограничьте память ваших процессов с помощью контрольных групп или подобных механизмов, чтобы один маргинальный код не влиял на другие процессы, запущенные в системе.
  2. Определите, что произойдет, когда ваша программа выйдет из строя из-за OOM (недостаточно памяти). Например, вы можете сделать дамп кучи, который впоследствии поможет найти причину утечки памяти.
  3. Не размещайте большие переменные в стеке. Убедитесь, что любой рекурсивный алгоритм завершается после достижения известной максимальной глубины. Если рекурсивный алгоритм может выполнять рекурсию неизвестное или большое количество раз, либо управляйте рекурсией самостоятельно (поддерживая собственный динамически выделяемый стек), либо преобразуйте рекурсивный алгоритм в эквивалентный итерационный алгоритм.
  4. Когда пространство выделяется с помощью семейства функций alloc, пространство выделяется постоянно, пока программа не завершится или не освободится. Поэтому убедитесь, что вы освобождаете эту динамически выделяемую память, когда она вам больше не нужна (по возможности, в основном в той же области).
  5. По возможности используйте статическое размещение. Статическая память выделяется при объявлении переменных, компилятор заранее знает размер переменной. Также такие переменные уничтожаются автоматически, когда закрывающая их функция завершает работу.

Итак, в следующий раз, прежде чем создавать запрос на вытягивание, просмотрите свой код и посмотрите, оптимизирован ли он для управления памятью.

Подпишитесь на нас, чтобы увидеть больше таких статей, вы также можете посетить addskill.io, чтобы узнать больше о нас.

Ссылки

  1. Основы управления памятью в c
  2. Основы управления памятью в c++
  3. Распространенные ошибки
  4. Хорошее чтение!