(РЕШЕНО) Heaptrc показывает утечку памяти...
Модератор: Модераторы
(РЕШЕНО) Heaptrc показывает утечку памяти...
Всем привет.
Может ли модуль Heaptrc ошибаться в такой ситуации?
В приложении последовательно создаются множество объектов. Сначала создается крупный объект - менеджер, в нем все остальные объекты при создании добавляются в свой список объектов. Менеджер владеет всеми списками объектов.
1) Один объект А из какого-либо списка может содержать ассоциации на другие объекты Б из других списков. Поэтому, когда первый объект А удаляется, в его деструкторе не вызывается метод Free объекта Б, а полю, ассоциированному с этим объектом, присваивается nil.
2) Также объект А может содержать список, в который ассоциированы множество объектов Б. Поскольку объекты Б входят уже в список менеджера, список объекта А создается со свойством ownobjects:=false. Т.е. при удалении списка из объекта А не происходит удаление входящих в него объектов. Вместо этого в деструкторе объекта А список объектов Б очищается (метод clear) и удаляется (free).
При завершении в деструкторе менеджера все списки удаляются, соответственно все входящие в них объекты также освобождают память.
================
Модуль Heaptrc НЕ показывает утечек в ситуации 1, т.е. когда есть ассоциации отдельных объектов.
Однако в ситуации 2 он начинает орать, что есть неосвобожденные куски памяти. Я уже на листе нарисовал всю последовательность создания всех объектов, всех списков и удаления их. Не вижу пробелов... Может ли быть это ошибкой? Или все-таки я мог что-то забыть.
В примере, в котором Heaptrc уже начинает орать, объект А создает список объектов Б, в который добавляется всего один объект Б (также он добавляется в список менеджера). При завершении объект А удаляется (список объектов Б внутри него очищается и удаляется), затем менеджер удаляет все списки, включая объекты А и Б. Не должно быть не удаленных объектов, но Heaptrc все равно орёт.
P.S. Я постарался максимально объяснить, но если б клал куски кода, то, наоборот, бы запутал только. Там оооочень много.
Может ли модуль Heaptrc ошибаться в такой ситуации?
В приложении последовательно создаются множество объектов. Сначала создается крупный объект - менеджер, в нем все остальные объекты при создании добавляются в свой список объектов. Менеджер владеет всеми списками объектов.
1) Один объект А из какого-либо списка может содержать ассоциации на другие объекты Б из других списков. Поэтому, когда первый объект А удаляется, в его деструкторе не вызывается метод Free объекта Б, а полю, ассоциированному с этим объектом, присваивается nil.
2) Также объект А может содержать список, в который ассоциированы множество объектов Б. Поскольку объекты Б входят уже в список менеджера, список объекта А создается со свойством ownobjects:=false. Т.е. при удалении списка из объекта А не происходит удаление входящих в него объектов. Вместо этого в деструкторе объекта А список объектов Б очищается (метод clear) и удаляется (free).
При завершении в деструкторе менеджера все списки удаляются, соответственно все входящие в них объекты также освобождают память.
================
Модуль Heaptrc НЕ показывает утечек в ситуации 1, т.е. когда есть ассоциации отдельных объектов.
Однако в ситуации 2 он начинает орать, что есть неосвобожденные куски памяти. Я уже на листе нарисовал всю последовательность создания всех объектов, всех списков и удаления их. Не вижу пробелов... Может ли быть это ошибкой? Или все-таки я мог что-то забыть.
В примере, в котором Heaptrc уже начинает орать, объект А создает список объектов Б, в который добавляется всего один объект Б (также он добавляется в список менеджера). При завершении объект А удаляется (список объектов Б внутри него очищается и удаляется), затем менеджер удаляет все списки, включая объекты А и Б. Не должно быть не удаленных объектов, но Heaptrc все равно орёт.
P.S. Я постарался максимально объяснить, но если б клал куски кода, то, наоборот, бы запутал только. Там оооочень много.
Последний раз редактировалось java73 03.12.2019 13:50:56, всего редактировалось 1 раз.
Re: Heaptrc показывает утечку памяти, хотя её не должно быть
java73 писал(а):Может ли модуль Heaptrc ошибаться
Ни разу пока не сталкивался с такой ситуацией. Желателен все же минимальный пример утечки.
Re: Heaptrc показывает утечку памяти, хотя её не должно быть
На сколько я понимаю логику Heaptrc - если в куче есть активные ссылочные части он их показывает.
Вообще он мне здорово помог при написании систем 24/7/365
Сигналил на объекты при удалении Object.Free, при них росла утечка памяти. Когда перешел на FreeAndNil(Object) - все стало ок.
Вообще он мне здорово помог при написании систем 24/7/365
Сигналил на объекты при удалении Object.Free, при них росла утечка памяти. Когда перешел на FreeAndNil(Object) - все стало ок.
Re: Heaptrc показывает утечку памяти, хотя её не должно быть
Блин))) ошибка как всегда скрывалась в невнимательности. Всё проще: heaptrc молодец, а я вот нет.
В этом коде прекрасно всё...за исключением TNiceClass.Create. Поскольку в следующем методе ReadNiceClass объект также создается.
Задвоение объектов выловил с помощью LazLogger, поставив лог в Сreate/Destroy:
В список попадал второй объект, а первый оставался болтаться в памяти неприкаянный.
Добавлено спустя 2 часа 49 минут 30 секунд:
Re: (РЕШЕНО) Heaptrc показывает утечку памяти...
А ведь два дня потратил.
Написал десяток тестов. Раскидал везде записей в логи. Два листа А4 вручную исписал процессами создания/удаления всех объектов. Обидно, что ошибка была нелепой и никак вообще не связанной с тем местом, где я искал первопричину.
Код: Выделить всё
lNice := TNiceClass.Create;
lNice := TIntel20Context(pContext).ReadNiceClass(Query.FieldByName('ID').AsInteger);
goodslist.Add(lNice); В этом коде прекрасно всё...за исключением TNiceClass.Create. Поскольку в следующем методе ReadNiceClass объект также создается.
Задвоение объектов выловил с помощью LazLogger, поставив лог в Сreate/Destroy:
Код: Выделить всё
+ create TNiceClass with ID=0
+ create TNiceClass with ID=2
+++ create a new object TTrademark with ID=1
Internal list of TtiObjectList free (0 objects)
- destroy TtiObjectList with ID=0
....
- destroy TNiceClass with ID=2
Internal list of TtiObjectList free (1 objects)В список попадал второй объект, а первый оставался болтаться в памяти неприкаянный.
Добавлено спустя 2 часа 49 минут 30 секунд:
Re: (РЕШЕНО) Heaptrc показывает утечку памяти...
А ведь два дня потратил.
Написал десяток тестов. Раскидал везде записей в логи. Два листа А4 вручную исписал процессами создания/удаления всех объектов. Обидно, что ошибка была нелепой и никак вообще не связанной с тем местом, где я искал первопричину.
Re: (РЕШЕНО) Heaptrc показывает утечку памяти...
java73 писал(а):Обидно, что ошибка была нелепой и никак вообще не связанной с тем местом, где я искал первопричину.
было бы обидно, если не нашел
Re: (РЕШЕНО) Heaptrc показывает утечку памяти...
А как откапывать проблему если в логе только адреса памяти во время работы?
Код: Выделить всё
168959 memory blocks allocated : 67278147/67831712
168958 memory blocks freed : 67278055/67831616
1 unfreed memory blocks : 92
True heap size : 950272 (128 used in System startup)
True free heap : 949936
Should be : 949952
Call trace for block $01E89B58 size 92
$0046D90A
$004034FB
$00508EDC
$0050CAC7
$00518BCC
$0051AB51
$0051AA88
$00433B4C
$00433A19
$005098EE
$0050D22F
$0050CE2A
$0050D441
$0050D2D0
$0051958E
$0051ADBC
Re: (РЕШЕНО) Heaptrc показывает утечку памяти...
собрать проект с включенной отладочной информацией и информацией о номерах строк -gw2 -gl
Re: (РЕШЕНО) Heaptrc показывает утечку памяти...
zub писал(а):собрать проект с включенной отладочной информацией и информацией о номерах строк -gw2 -gl
Спасибо, но не то. Отладочная информация всегда включена в автоматическом режиме. Попробовал ради интереса -gw2 не отображаются строки все равно. Пока делал вспомнил об одной проблеме Lazarus. Давно не прогонял через поиск утечек и забыл о ней. Проблема в русских буквах в путях.
Re: (РЕШЕНО) Heaptrc показывает утечку памяти...
отлинфа в внешнем файле?
Re: (РЕШЕНО) Heaptrc показывает утечку памяти...
zub писал(а):отлинфа в внешнем файле?
ага
Re: (РЕШЕНО) Heaptrc показывает утечку памяти...
Всегда остаётся вариант, сформировать MAP-файл и проверить адреса по нему
