2009-04-20 3 views
6

Я запускаю свое приложение на C++ на устройстве Intel Xscale. Проблема в том, что когда я запускаю приложение offtarget (Ubuntu) с Valgrind, он не обнаруживает утечек памяти.Утечка памяти в C++

Но когда я запускаю его в целевой системе, он начинается с свободной памяти 50 КБ и уменьшается до 2 К за ночь. Как поймать такую ​​утечку, которая не показана Вальгриндом?

+0

Есть ли у вас код, который отличается? Действительно ли это идентично? Если нет, то в чем разница. Просто быстрые мысли. –

+0

Я предполагаю, что вы имеете в виду: начинается с 50 kb * бесплатно *? – MSalters

+0

Да, он начинается с 50 КБ бесплатно. Да, есть и определенный код платформы. Но я отключил его во время его запуска в системе ontarget. Но, все тот же вопрос. – Ajay

ответ

3

Это может быть не фактическая утечка памяти, а, возможно, ситуация с увеличением использования памяти. Например, это может быть выделение постоянно возрастающей последовательности:

string s; 
for (i=0; i<n; i++) 
    s += "a"; 

50k не так много, может быть, вы должны перейти источник вручную и посмотреть, что может быть причиной проблемы.

+0

Ну, на самом деле он начинается с свободной памяти 50 КБ и заканчивается 2 КБ свободной памяти. Код составляет примерно около 1 000 000 строк. – Ajay

+0

Ну, это только утечка 48 КБ, извините, если это не настоящая утечка, вам, возможно, придется искать код для вероятных виновников ... как насчет распределения памяти журнала? –

+0

Если valgrind не показывает утечки, это наиболее вероятный сценарий. Это не значит, что это единственный, но это ситуация, которую не может обнаружить valgrind. Лучшее, что вы можете сделать, это записать ядра на диск с интервалами и сравнить их. Если вы обнаружите некоторый буфер, размер которого больше в каждом последующем дампе, изучите его код. Это утомительно, предоставлено ... – 2009-04-20 09:36:55

3

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

Возможные пути преодоления этого:

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

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

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

+0

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

0

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

Все, что я могу добавить, это то, что Valgrind, как известно, довольно эффективен при обнаружении утечек памяти!

0

Кроме того, вы уверены, что, когда вы профилировали свой код, покрытия кода были достаточными для покрытия всех кодов, которые могут быть выполнены на целевой платформе?

Valgrind наверняка не лжет. Как уже отмечалось, это действительно может быть кучей времени выполнения, который не освобождает память, но я бы подумал иначе.

0

Вы используете какой-либо сложный метод для отслеживания области действия объекта?? если да, то чем Valgrind не достаточно умны, хотя вы можете попробовать путем установки параметров, связанных с XScale с Valgrind

+0

Я не знаю никаких связанных с xscale опций в valgrind. Как это сделать? – Ajay

0

Большинство приложений показывают картину использования памяти, как это:

  • они используют очень мало, когда они начинают
  • , поскольку они создают структуры данных, они используют все больше и больше
  • , как они начинают удалять старые структуры данных или повторное использование существующих, они достигают стационарного состояния, где использование памяти остается примерно постоянной

Если ваше приложение постоянно увеличивается в размерах, вы можете иметь aleak. Если он увеличивается в течение периода апериода, а затем достигает равновесного состояния, вы, вероятно, этого не делаете.

10

Общепринятым преступником с этими маленькими встроенными детекторами является фрагментация памяти. У вас может быть свободная память в приложении между двумя объектами. Общим для этого решением является использование выделенного распределителя (оператора new на C++) для наиболее распространенных классов. Пулы памяти, используемые исключительно для объектов размера N, не фрагментируют - пространство между двумя объектами всегда будет кратным N.

1

Это звучит как фрагментация. Фрагментация вызывается вы выделения объектов в стеке, скажем:

object1
object2
object3
object4

и удалить некоторые объекты

object1

object3
object4

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

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

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

Один из способов сделать это, чтобы создать один статический:

struct Slot 
{ 
    Slot() : free(true) {} 
    bool free; 
    BYTE data[20]; // you'll need to tune the value 20 to what your program needs 
}; 
Slot pool[500]; // you'll need to pick a good pool size too. 

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

Затем переопределите новые и удалите операторы для подозрительного класса, чтобы они возвращали слоты из этого вектора. Таким образом, ваши объекты будут сохранены в этом векторе.

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

Создать пулы разных размеров для разных объектов.

Просто пойдите для худших нарушителей сначала.

Я уже делал что-то подобное раньше, и это решило мою проблему на встроенном устройстве. Я также использовал много STL, поэтому создал пользовательский распределитель (google для stl custom allocator - есть множество ссылок). Это было полезно для записей, хранящихся в мини-базе данных, используемой моей программой.

0

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