Модераторы: Poseidon, Snowy, bems, MetalFan

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> освобождение памяти при удалении узлов в дереве 
V
    Опции темы
uwannadie
Дата 4.4.2010, 11:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 175
Регистрация: 5.6.2009
Где: Крым, Керчь

Репутация: нет
Всего: 1



заполняю VirtualStringTree данными, имеющими следующую структуру
Код

type
  TFilePriority =
      (fpNormal,    //обычный файл
       fpCritical,  //файл, критический для корректной работы программы
       fpAbsolute); //файл, который будет обновляться в любом случае

type
  PFileInfo = ^TFileInfo;

  TFileInfo = record
    FileName: String; //полный путь к файлу
    TreeName: String; //название узла в дереве
    FilePriority: TFilePriority;
    ImageIndex: Byte;
  end;

Заполняется дерево следующим образом
Код

procedure TfrmCreateNewUpdate.FillTreeviewWithFiles(directory: string; pTree: TVirtualStringTree; pNode: PVirtualNode);
var
  Mysearch: TSearchRec;
  FldrNode: PVirtualNode;
  FileData: PFileInfo;
begin
  if directory[Length(directory)] <> '\' then
    directory := directory + '\';
  pTree.BeginUpdate;
  if FindFirst(directory + '*.*', faDirectory, Mysearch) = 0 then
  begin
    repeat
      //поиск папок
      if ((Mysearch.Attr and faDirectory) = faDirectory) and (Mysearch.Name[1] <> '.') then
      begin
        if (Mysearch.Attr and faDirectory > 0) then
        begin
          pNode := pTree.AddChild(pNode,nil);
          FileData := pTree.GetNodeData(pNode);
          if Assigned(FileData) then
          with FileData^ do
          begin
            FileName := Directory + Mysearch.Name;
            TreeName := Mysearch.Name;
            FilePriority := fpNormal;
            ImageIndex := 0;
          end;
        end;
        FldrNode := pNode.Parent;
        FillTreeviewWithFiles(directory + Mysearch.Name + '\', pTree, pNode);
        pNode := FldrNode;
      end;
    until FindNext(Mysearch) <> 0;
      FldrNode := pNode;
  if FindFirst(directory + '*.*', $23, Mysearch) = 0 then
  begin
    repeat
      //поиск файлов
      pNode := pTree.AddChild(FldrNode,nil);
      FileData := pTree.GetNodeData(pNode);
      if Assigned(FileData) then
      with FileData^ do
      begin
        FileName := Directory + Mysearch.Name;
        TreeName := Mysearch.Name;
        FilePriority := fpNormal;
        ImageIndex := 1;
      end;
    until FindNext(Mysearch) <> 0;
  end;
  FindClose(Mysearch);
  end;
  pTree.EndUpdate;
end;

в событии OnFreeNode написано следующее:
Код

procedure TfrmCreateNewUpdate.vtProjectFilesFreeNode(Sender: TBaseVirtualTree;
  Node: PVirtualNode);
var
  FileData: PFileInfo;
begin
  FileData := Sender.GetNodeData(Node);
  if Assigned(FileData) then
    Finalize(FileData^);
end;

вопрос: почему при удалении всех узлов дерева, последующем выполнение
Код

vtProjectFiles.Clear;

и заполнении дерева аналогичными данными объем занимаемой памяти увеличивается. при этом FastMM ругается на утечки памяти:
Код

--------------------------------2010/4/3 22:38:40--------------------------------
This application has leaked memory. The small block leaks are (excluding expected leaks registered by pointer):

21 - 36 bytes: UnicodeString x 1617
37 - 52 bytes: UnicodeString x 1962
53 - 68 bytes: UnicodeString x 459
69 - 84 bytes: TStringList x 1, UnicodeString x 84
85 - 100 bytes: UnicodeString x 90
101 - 116 bytes: UnicodeString x 33
117 - 132 bytes: UnicodeString x 21
133 - 148 bytes: UnicodeString x 42
149 - 164 bytes: UnicodeString x 54
165 - 180 bytes: UnicodeString x 54
181 - 212 bytes: UnicodeString x 1974
213 - 244 bytes: UnicodeString x 1290
245 - 276 bytes: UnicodeString x 516
277 - 308 bytes: UnicodeString x 99
309 - 340 bytes: UnicodeString x 12
341 - 388 bytes: UnicodeString x 3


--------------------
PM MAIL   Вверх
Dom
Дата 4.4.2010, 16:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 121
Регистрация: 7.8.2005

Репутация: 1
Всего: 4



Хм, наугад - утечки UnicodeString, а поля в записи типа String. Какая версия Делфи? Может это утечки и не в дереве?

Ну и можно попробовать освобождать память, вручную затирая строки:
Код

procedure TfrmCreateNewUpdate.vtProjectFilesFreeNode(Sender: TBaseVirtualTree;
  Node: PVirtualNode);
var
  FileData: PFileInfo;
begin
  FileData := Sender.GetNodeData(Node);
  if Assigned(FileData) then
    with FileData^ do
    begin
      FileName := '';
      TreeName := '';
    end;
end;

PM MAIL   Вверх
uwannadie
Дата 4.4.2010, 16:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 175
Регистрация: 5.6.2009
Где: Крым, Керчь

Репутация: нет
Всего: 1



пробовал, перед тем, как создавать тему. не помогает
RAD Studio 2010 Architect

Это сообщение отредактировал(а) uwannadie - 4.4.2010, 16:27
--------------------
PM MAIL   Вверх
kami
Дата 4.4.2010, 16:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1806
Регистрация: 25.8.2007
Где: Санкт-Петербург

Репутация: 23
Всего: 72



Из лога FastMM приведен только конец. Самое интересное - в нем фигурирует TstringList, а в приведенном коде его не наблюдается. Смотри по полному логу, где он (TStringList) создается и уничтожается.
PM MAIL WWW   Вверх
uwannadie
Дата 4.4.2010, 16:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 175
Регистрация: 5.6.2009
Где: Крым, Керчь

Репутация: нет
Всего: 1



при всем этом программа обрабатывает данные без сучка и задоринки, но если раз 10-12 очистить и заполнить дерево аналогичными данными, то размер программы в оперативке легко возрастает до 50-60 мб
--------------------
PM MAIL   Вверх
Dom
Дата 4.4.2010, 16:35 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 121
Регистрация: 7.8.2005

Репутация: 1
Всего: 4



Так может все-таки дело действительно не в записях дерева, если ручное затирание не помогает?
Может попробовать не очищать узлы в дереве и посмотреть добавятся в этом случае новые утечки или нет? По идее должны, хотя как работают новые версии Делфи я не знаю, знаком только с Д7. Если добавятся, то это уже точно будут из дерева, и следовательно нынешние вызваны чем-то другим.
PM MAIL   Вверх
uwannadie
Дата 4.4.2010, 16:35 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 175
Регистрация: 5.6.2009
Где: Крым, Керчь

Репутация: нет
Всего: 1



Цитата(kami @ 4.4.2010,  16:33)
Из лога FastMM приведен только конец. Самое интересное - в нем фигурирует TstringList, а в приведенном коде его не наблюдается. Смотри по полному логу, где он (TStringList) создается и уничтожается.

стринглист освобождается в другом месте. в нем находится список http ссылок (а-ля зеркал обновления). 
--------------------
PM MAIL   Вверх
kami
Дата 4.4.2010, 16:39 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1806
Регистрация: 25.8.2007
Где: Санкт-Петербург

Репутация: 23
Всего: 72



Цитата(uwannadie @  4.4.2010,  16:35 Найти цитируемый пост)
стринглист освобождается в другом месте. 

Значит не освобождается. Или освобождается, но не тот. Смотри ПОЛНЫЙ лог, найди в нем поиском сообщение о создании и не-высвобождении TStringList (будет дано всё, вплоть до конкретной строчки модуля). Оттуда и плясать.
PM MAIL WWW   Вверх
uwannadie
Дата 4.4.2010, 16:40 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 175
Регистрация: 5.6.2009
Где: Крым, Керчь

Репутация: нет
Всего: 1



вот создание данного списка
Код

procedure TfrmCreateNewUpdate.sbtnSettingsSelectClick(Sender: TObject);
begin
  if not SelectDirectory('Укажите путь к клиентской части системы обновления','', SettingsPath) then Exit
  else
    lbeUpdClientpath.Text := SettingsPath;
  if not FileExists(SettingsPath + '\settings.ini') then
  begin
    UpdateMirrors := TStringList.Create;
    UpdateRev := 1;
    seUpdRev.MinValue := UpdateRev;
    lbeRelativePathToExe.Text := '';
    btnUpdMirrors.Enabled := True;
    btnSaveINI.Enabled := True;
    seUpdRev.Enabled := True;
  end;
end;

вот освобождение памяти
Код

procedure TfrmCreateNewUpdate.btnSaveINIClick(Sender: TObject);
var
  MyINI: TIniFile;
  i: integer;
begin
  DeleteFile(SettingsPath + '\settings.ini');
  MyINI := TIniFile.Create(SettingsPath + '\settings.ini');
  MyINI.WriteString('Client Settings','RelativePath', lbeRelativePathToExe.Text);
  MyINI.WriteInteger('Client Settings','UpdateRevision', UpdateRev);
  MyINI.WriteInteger('Update Mirrors','Count', UpdateMirrors.Count);
  for I := 0 to  UpdateMirrors.Count - 1 do
    MyINI.WriteString('Update Mirrors','Mirror#' + IntToStr(i + 1),UpdateMirrors.Strings[i]);
  MyINI.Free;
  UpdateMirrors.Free;
end;



--------------------
PM MAIL   Вверх
kami
Дата 4.4.2010, 16:46 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1806
Регистрация: 25.8.2007
Где: Санкт-Петербург

Репутация: 23
Всего: 72



Цитата(uwannadie @  4.4.2010,  16:40 Найти цитируемый пост)
вот освобождение памяти

FastMM говорит именно об этом списке?
PM MAIL WWW   Вверх
uwannadie
Дата 4.4.2010, 16:51 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 175
Регистрация: 5.6.2009
Где: Крым, Керчь

Репутация: нет
Всего: 1



у меня в программе он единственный (по-крайней мере я больше не создавал)
--------------------
PM MAIL   Вверх
Dom
Дата 4.4.2010, 16:55 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 121
Регистрация: 7.8.2005

Репутация: 1
Всего: 4



В целом немного необычно, когда глобальнае переменная создается по одной кнопке и уничтожается по другой. Обычно я например ставлю это в процедуры создания/удаления формы. А в теле процедур использую Clear. Ведь если кнопка сохранить (вторая процедура) нажата не будет, то список не очистится. А при повторном вызове первой процедуры, возникнет утечка памяти.
PM MAIL   Вверх
kami
Дата 4.4.2010, 16:57 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1806
Регистрация: 25.8.2007
Где: Санкт-Петербург

Репутация: 23
Всего: 72



Цитата(uwannadie @  4.4.2010,  16:51 Найти цитируемый пост)
у меня в программе он единственный (по-крайней мере я больше не создавал)

Читай, пожалуйста, сообщения полностью. В частности:
Цитата(kami @  4.4.2010,  16:39 Найти цитируемый пост)
 Смотри ПОЛНЫЙ лог, найди в нем поиском сообщение о создании и не-высвобождении TStringList (будет дано всё, вплоть до конкретной строчки модуля). Оттуда и плясать.

Если в логе идут только адреса, то нужно включить в опциях проекта Debug information и include TD32 debug Info. В D7 первая находится в закладке Compiler а вторая на закладке Linker. После этого сделать Build проекту, удалить старый лог и запустить программу для генерации нового.

Добавлено через 1 минуту и 7 секунд
Цитата(Dom @  4.4.2010,  16:55 Найти цитируемый пост)
В целом немного необычно,

+много необычно smile
PM MAIL WWW   Вверх
uwannadie
Дата 4.4.2010, 17:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 175
Регистрация: 5.6.2009
Где: Крым, Керчь

Репутация: нет
Всего: 1



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

procedure TfrmCreateNewUpdate.SaveNodesToFile(pTree: TBaseVirtualTree; pNode: PVirtualNode; var NodeList: TStringList);
var
  FileData: PFileInfo;
  TempNode: PVirtualNode;
begin
  if pNode.ChildCount > 0 then
  begin
    TempNode := pNode.FirstChild;
    repeat
      begin
        if TempNode.ChildCount = 0 then
        begin
          FileData := pTree.GetNodeData(TempNode);
          NodeList.Add(FilePriorityToStringEx(FileData^.FilePriority) +
                       '|' + FileData^.FileName);
        end;
        SaveNodesToFile(pTree, TempNode, NodeList);
        TempNode := TempNode.NextSibling;
      end;
    until (TempNode = nil);
  end;
end;

ругается везде на:
Код

NodeList.Add(FilePriorityToStringEx(FileData^.FilePriority) + '|' + FileData^.FileName);
.....
SaveNodesToFile(pTree, TempNode, NodeList); 

остальные утечки, судя по номерам строк, завязаны на реализации механизма поиска файлов в делфи
--------------------
PM MAIL   Вверх
Dom
Дата 4.4.2010, 17:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 121
Регистрация: 7.8.2005

Репутация: 1
Всего: 4



Отлично. Теперь осталось корректно освободить память от NodeList. После этого какие-то утечки еще остаются?
PM MAIL   Вверх
Страницы: (3) Все [1] 2 3 
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Delphi: Общие вопросы"
SnowyMetalFan
bemsPoseidon
Rrader

Запрещается!

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

  • Литературу по Дельфи обсуждаем здесь
  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь
  • 90% ответов на свои вопросы можно найти в DRKB (Delphi Russian Knowledge Base) - крупнейшем в рунете сборнике материалов по Дельфи


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Snowy, MetalFan, bems, Poseidon, Rrader.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Delphi: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.1961 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.