Как Вы обнаруживаете/избегаете Утечки памяти в своем (Неуправляемом) коде? [закрытый]

tl; dr: Нет! Функции стрелок и декларации функций / выражения не являются эквивалентными и не могут быть заменены вслепую. Если функция, которую вы хотите заменить, not использует this, arguments и не вызывается с new, тогда да.


Как это часто бывает: это зависит. Функции Arrow имеют другое поведение, чем декларации / выражения функций, поэтому давайте сначала рассмотрим различия:

1. Функции Lexical this и arguments

не имеют собственных привязок this или arguments. Вместо этого эти идентификаторы разрешаются в лексической области, как и любая другая переменная. Это означает, что внутри функции стрелки this и arguments относятся к значениям this и arguments в окружающей среде, функция стрелки определена в (т.е. «снаружи» стрелка )

В случае выражения функции, this относится к объекту, который был создан внутри createObject. В функциональном случае стрелки this относится к this самого createObject.

Это делает функции стрелок полезными, если вам нужно получить доступ к this текущей среды:

// currently common pattern
var that = this;
getData(function(data) {
  that.data = data;
});

// better alternative with arrow functions
getData(data => {
  this.data = data;
});

Обратите внимание, что это также означает, что не можно установить функцию стрелки this с .bind или .call.

Если вы не очень знакомы с this, рассмотрим чтение

2. Функции стрелок не могут быть вызваны с помощью new

ES2015 различает функции, доступные call , и функции, которые являются конструкцией . Если функция конструируется, ее можно вызвать с помощью new, то есть new User(). Если функция является вызываемой, ее можно вызвать без new (т. Е. Вызов нормальной функции).

Функции, созданные посредством деклараций / выражений функций, являются конструктивными и вызываемыми. Функции стрелок (и методы) являются только вызываемыми. class конструкторы только конструктивны.

Если вы пытаетесь вызвать функцию, не вызываемую вызовом, или построить неконструируемую функцию, вы получите ошибку времени выполнения.


Зная это, мы можем указать следующее.

Сменный:

  • Функции, которые не используют this или arguments.
  • Функции, которые используются с .bind(this)

Не сменный:

  • Функции конструктора
  • Функция / методы, добавленные к прототипу (поскольку они обычно используют функции this)
  • Variadic (если они используют arguments (см. ниже))

Давайте рассмотрим это более подробно с помощью ваших примеров:

Функция конструктора

Это не будет работать, потому что функции стрелок нельзя вызвать с помощью new. Продолжайте использовать объявление / выражение функции или используйте class.

Способы прототипа

Скорее всего нет, потому что методы прототипа обычно используют this для доступа к экземпляру. Если они не используют this, вы можете его заменить. Однако, если вы в первую очередь заботитесь о сжатом синтаксисе, используйте class с его синтаксисом сжатого метода:

class User {
  constructor(name) {
    this.name = name;
  }

  getName() {
    return this.name;
  }
}

Методы объекта

Аналогично для методов в объектном литерале. Если метод хочет ссылаться на сам объект через this, продолжайте использовать функциональные выражения или используйте новый синтаксис метода:

const obj = {
  getName() {
    // ...
  },
};

Обратные вызовы

Это зависит. Вы должны обязательно заменить его, если вы наложили внешний this или используете .bind(this):

// old
setTimeout(function() {
  // ...
}.bind(this), 500);

// new
setTimeout(() => {
  // ...
}, 500);

Но: Если код, вызывающий обратный вызов, явно устанавливает this на определенное значение , как это часто бывает с обработчиками событий, особенно с jQuery, и обратный вызов использует this (или arguments), вы не можете использовать функцию стрелки!

Variadic функции

Поскольку функции стрелок не имеют собственных arguments, вы не можете просто заменить их функцией стрелки. Однако ES2015 вводит альтернативу использованию arguments: параметр rest .

// old
function sum() {
  let args = [].slice.call(arguments);
  // ...
}

// new
const sum = (...args) => {
  // ...
};

Связанный вопрос:

Дополнительные ресурсы:

123
задан 4 revs, 3 users 62% 22 August 2017 в 17:17
поделиться

28 ответов

Если Ваш код C/C++ является портативным к *, отклоняют, немного вещей лучше, чем Valgrind.

78
ответ дан 24 November 2019 в 01:13
поделиться

Обнаружьте:

CRT

Отладки Избегайте:

Интеллектуальные указатели, boehm GC

0
ответ дан 24 November 2019 в 01:13
поделиться

Хороший malloc, calloc и reallloc замена являются rmdebug, это довольно просто в использовании. Это намного быстрее к затем valgrind, таким образом, можно протестировать код экстенсивно. Конечно, это имеет некоторые оборотные стороны, после того как Вы нашли утечку, вероятно, все еще необходимо использовать valgrind для нахождения, где утечка появляется, и можно только протестировать mallocs, который Вы делаете непосредственно. Если lib протечет, потому что Вы используете его неправильно, rmdebug не найдет его.

http://www.hexco.de/rmdebug/

0
ответ дан 24 November 2019 в 01:13
поделиться

Valgrind является хорошей опцией для Linux. В соответствии с MacOS X, можно включить библиотеку MallocDebug, которая имеет несколько опций для отладки проблем выделения памяти (см. malloc страницу справочника, раздел "ENVIRONMENT" имеет соответствующие детали). SDK OS X также включает инструмент под названием MallocDebug (обычно устанавливаемый в/Developer/Applications/Performance Инструментах/), который может помочь Вам контролировать использование и утечки.

0
ответ дан 24 November 2019 в 01:13
поделиться

По крайней мере, для MS VC ++, Библиотека времени выполнения C имеет несколько функций, которые я нашел полезными в прошлом. Проверьте справку MSDN на _Crt* функции.

1
ответ дан 24 November 2019 в 01:13
поделиться

mmgr Paul Nettle является моим долговременным инструментом фаворита. Вы включаете mmgr.h в свои исходные файлы, определяете TEST_MEMORY, и он поставляет текстовый файл, полный проблем памяти, которые произошли во время выполнения Вашего приложения.

1
ответ дан 24 November 2019 в 01:13
поделиться

Общая Инструкция по Кодированию:

  • Ресурсы должны быть освобождены на том же "слое" (функция/класс/библиотека), где они выделяются.
  • , Если это не возможно, попытайтесь использовать некоторое автоматическое освобождение (повышение совместно использованный указатель...)
1
ответ дан 24 November 2019 в 01:13
поделиться

Работая над операционной системой сотовых телефонов Motorola, мы похитили библиотеку выделения памяти для наблюдения всех выделений памяти. Это помогло найти много проблем с выделениями памяти. Так как предотвращение лучше затем исправляет, я рекомендовал бы использовать инструмент статического анализа как Klockwork или Линт ПК

1
ответ дан 24 November 2019 в 01:13
поделиться

Вы считаете выделения, и освобождает путем интерполяции собственных функций syscall, которые записывают вызовы и затем передают вызов реальной функции?

Это - единственный способ, которым можно отслеживать вызовы, происходящие из кода, который Вы не написали.

Взглянули на страницу справочника для ld.so. Или ld.so.1 в некоторых системах.

Также делают Google LD_PRELOAD, и Вы найдете некоторые интересные статьи, объясняющие технику на www.itworld.com.

2
ответ дан 24 November 2019 в 01:13
поделиться

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

А очень полный и быстрый инструмент.

2
ответ дан 24 November 2019 в 01:13
поделиться

Лучшая защита против утечек является структурой программы, которая минимизирует использование malloc. Это не только хорошо с точки зрения программирования, но также и улучшает производительность и пригодность для обслуживания. Я не говорю об использовании других вещей вместо malloc, но с точки зрения многократного использования объектов и хранения очень явных вкладок на всех объектах, раздаваемых вместо того, чтобы выделить волей-неволей как, каждый часто привыкает к на языках со сборщиками "мусора" как Java.

, Например, программа, я продолжаю работать, имеет набор объектов кадра, представляющих данные изображения. Каждый объект кадра имеет подданные, которые освобождает деструктор кадра. Программа сохраняет список всех кадров, которые выделяются, и когда она нуждается в новом, проверяет, что список неиспользованного кадра возражает, чтобы видеть, может ли она снова использовать существующий, а не выделить новый. На завершении работы это просто выполняет итерации через список, освобождая все.

2
ответ дан 24 November 2019 в 01:13
поделиться

Визуальный Детектор Утечки является очень хорошим инструментом, хотя он не делает поддерживает запросы ко времени выполнения VC9 (MSVCR90D.DLL, например).

7
ответ дан 24 November 2019 в 01:13
поделиться

При использовании Visual Studio, на это могло бы стоить посмотреть Средство проверки Границ . Это не свободно, но это было невероятно полезно в нахождении утечек в моем коде. Это только делает утечки памяти также, но также и утечки ресурсов GDI, ошибки использования WinAPI и другой материал. Это даже покажет Вам, где пропущенная память была инициализирована, делая намного легче разыскать утечку.

3
ответ дан 24 November 2019 в 01:13
поделиться

Существует различная замена "malloc" библиотеки там, которые позволят Вам вызывать функцию в конце, и это скажет Вам обо всей неосвобожденной памяти, и во многих случаях, кто malloced (или new'ed) это во-первых.

4
ответ дан 24 November 2019 в 01:13
поделиться

Я думаю, что нет никакого легкого ответа на этот вопрос. Как Вы могли бы действительно приблизиться, это решение зависит от Ваших требований. Вам нужно кросс-платформенное решение? Вы используете новый/удаляющий или malloc/free (или оба)? Вы действительно ищете просто "утечки", или Вы хотите лучшую защиту, такую как обнаружение переполнения буфера (или недогрузки)?

, Если Вы работаете над стороной окон, библиотеки времени выполнения отладки MS имеют некоторую основную функциональность обнаружения отладки, и как другой уже указал, существует несколько оберток, которые могут быть включены в Ваш источник для помощи с обнаружением утечки. Нахождение пакета, который может работать и с новым/удаляющим и с malloc/free, очевидно, дает Вам больше гибкости.

я не знаю достаточно о стороне Unix для обеспечения справки, хотя снова, другие имеют.

, Но вне просто обнаружения утечки, существует понятие обнаружения повреждения памяти через переполнение буфера (или недогрузки). Этот тип функциональности отладки, я думаю более трудный, чем простое обнаружение утечки. Этот тип системы является также далее сложным, если Вы работаете с объектами C++, потому что polymorhpic классы могут быть удалены в переменных способах вызвать ловкость в определении истинного указателя базы, который удаляется. Я не знаю ни о какой хорошей "свободной" системе, которая делает достойную защиту для переполнений. мы записали (кросс-платформенную) систему и нашли, что это было довольно сложно.

2
ответ дан 24 November 2019 в 01:13
поделиться

Если Вы используете MS VC ++, я могу настоятельно рекомендовать этот бесплатный инструмент от codeproject: leakfinder Jochen Kalmbach.

Вы просто добавляете класс к своему проекту и вызов

InitAllocCheck(ACOutput_XML)
DeInitAllocCheck()

прежде и после кода, который Вы хотите проверить на утечки.

, После того как Вы имеете сборку и выполняете код, Jochen обеспечивает аккуратный инструмент GUI, где можно загрузить получающийся .xmlleaks файл и перейти через стек вызовов, где каждая утечка была сгенерирована для выслеживания незаконной строки кода.

Rational (теперь принадлежавший IBM) PurifyPlus иллюстрирует утечки подобным способом, но я нахожу leakfinder инструмент на самом деле легче использовать с премией его не стоение нескольких тысяч долларов!

4
ответ дан 24 November 2019 в 01:13
поделиться

Никогда не использовал его самостоятельно, но мои друзья C говорят мне , Очищают .

3
ответ дан 24 November 2019 в 01:13
поделиться

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

  1. Вы могли бы найти это полезным.

  2. , Хотя это является немного неработоспособным, я не позволяю этому смутить меня.

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

существуют вещи, которых необходимо остерегаться при использовании его: не делайте ничего, что должно облокотиться new в базовом коде, остерегаться предупреждений о случаях, которые он мог бы пропустить наверху leakcheck.cpp, понять, что, если Вы включаете (и устраняют любые проблемы с) код, который действительно отображает дампы, можно генерировать огромный файл.

дизайн предназначен, чтобы позволить Вам включать и выключать средство проверки, не перекомпилировав все, что включает его заголовок. Включайте leakcheck.h, где Вы хотите отследить проверку и восстановить однажды. После этого скомпилируйте leakcheck.cpp с или без LEAKCHECK #define'd и затем повторно свяжитесь для включения и выключения его. Включая unleakcheck.h выключит его локально в файле. Два макросов обеспечиваются: CLEARALLOCINFO () постарается не сообщать о том же файле и строке неуместно, когда Вы пересечете код выделения, который не включал leakcheck.h. ALLOCFENCE () просто написал в сгенерированном отчете, не делая никакого выделения.

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

можно найти его здесь: http://www.cse.ucsd.edu/~tkammeye/leakcheck.html

2
ответ дан 24 November 2019 в 01:13
поделиться

I’m не поразил никакой упомянутый DebugDiag для Windows OS.
Это работает над сборками конечных версий, и даже на сайте для клиентов.
(Просто необходимо сохранить версию выпуска PDBs и настроить DebugDiag для использования сервера символов общественности Microsoft)

10
ответ дан 24 November 2019 в 01:13
поделиться

Microsoft VC ++ в режиме отладки показывает утечки памяти, хотя она не показывает, где Ваши утечки.

при использовании C++, можно всегда избегать использования новый явно: Вы имеете vector, string, auto_ptr (пред C++ 11; замененный unique_ptr в C++ 11), unique_ptr (C++ 11) и shared_ptr (C++ 11) в Вашем арсенале.

, Когда новый неизбежно, попытайтесь скрыться, это в конструкторе (и скрыться удаляют в деструкторе); те же работы для сторонних API.

7
ответ дан 24 November 2019 в 01:13
поделиться

Для Linux: Попробуйте Google Perftools

, Там много инструментов, которые делают подобное выделение / бесплатный подсчет, профессионалов Goolge Perftools:

  • Довольно быстрый (по сравнению с valgrind: очень быстро)
  • Идет с хорошим графическим дисплеем результатов
  • , Имеет другие полезные возможности: профилирование CPU, профилирование использования памяти...
2
ответ дан 24 November 2019 в 01:13
поделиться

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

Запросы Выделения "кучи" Отслеживания - конкретно раздел по Уникальным Числам Запроса Выделения

_CrtSetDbgFlag

_CrtSetBreakAlloc

, Конечно, если Вы не используете DevStudio затем, это не будет особенно полезно.

16
ответ дан 24 November 2019 в 01:13
поделиться

Поскольку Разработчик C++ здесь - некоторые просто инструкции:

  1. указатели Использования только, когда абсолютно необходимый
  2. , Если Вам нужен указатель, перепроверка, если SmartPointer является возможностью
  3. Использование СХВАТЫВАНИЕ Создатель шаблон.

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

28
ответ дан 24 November 2019 в 01:13
поделиться

В C++: используйте RAII. Интеллектуальные указатели как std::unique_ptr, std::shared_ptr, std::weak_ptr являются Вашими друзьями.

37
ответ дан 24 November 2019 в 01:13
поделиться

При использовании Visual Studio Microsoft обеспечивает некоторые полезные функции для обнаружения и отладки утечек памяти.

я запустил бы с этой статьи: https://msdn.microsoft.com/en-us/library/x98tx3cf (v=vs.140) .aspx

Вот быстрая сводка тех статей. Во-первых, включайте эти заголовки:

#define _CRTDBG_MAP_ALLOC
#include <stdlib.h>
#include <crtdbg.h>

Затем необходимо назвать это, когда программа выходит:

_CrtDumpMemoryLeaks();

, С другой стороны, если Ваша программа не выходит в том же месте каждый раз, можно назвать это в начале программы:

_CrtSetDbgFlag ( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF );

Теперь то, когда программа выходит из всех выделений, которые не были free'd, будет распечатано в Окне вывода наряду с файлом, они были выделены в и возникновение выделения.

Эта стратегия работает на большинство программ. Однако это становится трудным или невозможным в определенных случаях. При пользовании сторонними библиотеками, которые, некоторая инициализация на запуске может вызвать другие объекты появиться в дампе памяти и может сделать разыскивание утечек трудным. Кроме того, если какой-либо из Ваших классов будет иметь участников с тем же именем как какая-либо из стандартных программ выделения памяти (таких как malloc), то макросы отладки CRT вызовут проблемы.

существуют другие методы, объясненные в ссылке MSDN, на которую ссылаются выше этого, мог использоваться также.

65
ответ дан 24 November 2019 в 01:13
поделиться

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

  1. Напишите код выпуска сразу после написания кода получения ресурсов, которые вы хотите выделить. С помощью этого метода труднее «забыть» и в некотором смысле заставляет серьезно задуматься о жизненном цикле ресурсов, которые используются заранее, а не как побочные.

  2. Используйте отдачу как можно реже. То, что выделено, по возможности следует освобождать только в одном месте. Условный путь между получением ресурса и выпуском должен быть максимально простым и очевидным.

1
ответ дан 24 November 2019 в 01:13
поделиться

Mtrace appears to be the standard built-in one for linux. The steps are :

  1. set up the environment variable MALLOC_TRACE in bash
    MALLOC_TRACE=/tmp/mtrace.dat
    export MALLOC_TRACE;
  2. Add #include to the top of you main source file
  3. Add mtrace(); at the start of main and muntrace(); at the bottom (before the return statement)
  4. compile your program with the -g switch for debug information
  5. run your program
  6. display leak info with
    mtrace your_prog_exe_name /tmp/mtrace.dat
    (I had to install the mtrace perl script first on my fedora system with yum install glibc_utils )
-1
ответ дан 24 November 2019 в 01:13
поделиться

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

Что, если вы только что заметили, что производственная система сейчас протекает, и вы не знаете, как воспроизвести это в тесте? Некоторое свидетельство того, что не так, фиксируется в состоянии этой производственной системы, и этого может быть достаточно, чтобы понять, где находится проблема, чтобы вы могли ее воспроизвести.

Вот здесь-то и появляется выборка Монте-Карло. Прочтите статью в блоге Раймонда Чена, «Способ бедняков определять утечки памяти», а затем проверить мою реализацию (предполагается, что Linux, протестирован только на x86 и x86-64)

http://github.com/tialaramex/leakdice/tree/master

1
ответ дан 24 November 2019 в 01:13
поделиться