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

Поиск:

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


Бывалый
*


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

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



память освобождается, но вне процедуры:
Код

FileList := TStringList.Create;
SaveNodesToFile(vtProjectFiles, vtProjectFiles.RootNode, FileList);
...
FileList.Free;


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


Эксперт
***


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

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



Это всё, что Вас просили показать?
Удачи Вам.
PM MAIL WWW   Вверх
uwannadie
Дата 4.4.2010, 19:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


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

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



последовал совету Dom, вынеся создание стриглистов в событие OnCreate формы а освобождение памяти в событие OnClose. в итоге остались лишь проблемы с памятью, связанные с тем, что RAD studio видимо все переменные типа String приводит к UnicodeString для поддержки юникода.

kami,Dom  - спасибо за Ваше время и Ваши нервы, потраченные на решение проблемы.

Добавлено @ 19:12
вот нашел обьяснение утечкам памяти:
Код

Таким образом, присвоение типа UnicodeString типу AnsiString может привести к потере данных. 
То есть если строка UnicodeString содержит данные со старшими байтами, преобразование такой строки в 
строку AnsiString приведет к потере старших байтов данных. 

© http://www.citforum.ru/programming/delphi/unicode/1.shtml

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


Эксперт
***


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

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



Цитата(uwannadie @  4.4.2010,  19:09 Найти цитируемый пост)
в итоге остались лишь проблемы с памятью, связанные с тем, что RAD studio видимо все переменные типа String приводит к UnicodeString для поддержки юникода.

Т.е. FastMM продолжает выдавать утечки?
В таком случае - проблема решена не полностью. В отлаженном приложении утечек быть не будет. Исключение я знаю только одно - в 9-й версии Indy была проблема с не-высвобождением чего-то из "внутренностей". При использовании стандартных компонент (VT можно отнести к ним) утечек быть не должно. Если есть - проблема в своем коде.

Лог после исправления части утечек в студию, пожалуйста.
PM MAIL WWW   Вверх
uwannadie
Дата 4.4.2010, 19:38 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


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

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



ругается постоянно на 2 строчки в процедуре

Код

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; //<<<< тут ругается (328 строка в модуле)
        TreeName := Mysearch.Name;
        FilePriority := fpNormal;
        ImageIndex := 1;
      end;
    until FindNext(Mysearch) <> 0; //<<<<<тут ругается (333 строка в модуле)
  end;
  FindClose(Mysearch);
  end;
  pTree.EndUpdate;
end;

еще ругается на 1 строчку в модуле с реализацией потока
Код

procedure TBuildThread.Execute;
var
  i: Integer;
  SourcePath: String;
  DestinationPath: String;
  pList: TIniFile;
begin
  DeleteFile(PChar(DestinationFolder + '\update.txt'));
  pList := TIniFile.Create(DestinationFolder + '\update.txt');
  pList.WriteInteger('Updater','File Count', pFileList.Count - 1);
    Synchronize(SetTotalProgressMax);
    for i := 0 to pFileList.Count - 1 do
  begin
    if Terminated then Exit;
    pFilePath := Copy(pFileList.Strings[i],Pos('|', pFileList.Strings[i]) + 1 ,
                        Length(pFileList.Strings[i]) - Pos('|', pFileList.Strings[i]));
    SourcePath := SourceFolder + pFilePath;
    DestinationPath := DestinationFolder + '\Updates' + ExtractDiffPath(pSourceFolder, pFilePath);
    pFileHash := IntToHex(FileCRC64(pFilePath), 16);
    Synchronize(UpdateCaption);
    pCriticalSection := Copy(pFileList.Strings[i], 0, Pos('|', pFileList.Strings[i]) - 1); // <<< тут ругается (136 строчка в модуле)
    pFileSize := GetFileSizeEx(pFilePath);
    pList.WriteString('File' + IntToStr(i),'Path',ExtractDiffPath(pSourceFolder, pFilePath));
    pList.WriteString('File' + IntToStr(i),'Url', ChangeSeparator('\Updates' + ExtractDiffPath(pSourceFolder, pFilePath)));
    pList.WriteString('File' + IntToStr(i),'Priority', pCriticalSection);
    pList.WriteInteger('File' + IntToStr(i),'Size', pFileSize);
    pList.WriteString('File' + IntToStr(i),'Hash', pFileHash);
    ForceDirectories(ExtractFilePath(DestinationPath));
    CompressFile(pFilePath, DestinationPath + '.bz2');
    pTotalProgress := i;
    Synchronize(UpdateTotalProgress);
  end;
  pFilePath := '';
  Synchronize(UpdateCaption);
  Synchronize(SetTotalProgressMax);
  pList.Free;
  Synchronize(UpdateControlsState);
end;

прикрепил лог работы 

Присоединённый файл ( Кол-во скачиваний: 4 )
Присоединённый файл  UpdateManager_MemoryManager_EventLog.rar 43,17 Kb
--------------------
PM MAIL   Вверх
kami
Дата 4.4.2010, 19:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


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

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



В OnFreeNode вместо Finalize(FileData^) поставьте Dispose(FileData). по результатам будем смотреть дальше, но Finalize не предназначено для корректного высвобождения строк.
PM MAIL WWW   Вверх
uwannadie
Дата 4.4.2010, 20:00 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


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

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



пробовал уже давно, вылезает "Exception: Invalid Pointer Operation"
--------------------
PM MAIL   Вверх
kami
Дата 4.4.2010, 20:18 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


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

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



Цитата(uwannadie @  4.4.2010,  20:00 Найти цитируемый пост)
пробовал уже давно, вылезает "Exception: Invalid Pointer Operation"

Понятно, ведь New не было вызвано, а они работают только в связке...
Сделайте так (в FillTreeviewWithFiles), Dispose оставьте на месте:
Код

New(FileData);
pNode:=pTree.AddChild(pNode, FileData);

// возможно, GetNodeData следующей строкой будет нужно, не помню, а делать тестовый проект неохота :)
if Assigned(FileData) then
  with FileData^ do
     begin
       FileName := Directory + Mysearch.Name;
       TreeName := Mysearch.Name;
       FilePriority := fpNormal;
       ImageIndex := 0;
.....



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


Бывалый
*


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

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



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


Шустрый
*


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

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



Немного не по теме
Цитата(kami @  4.4.2010,  19:49 Найти цитируемый пост)
но Finalize не предназначено для корректного высвобождения строк. 

Почему, или это исключительно для UnicodeString? В хелпе Д7 написано:
Цитата

Finalize simply sets all long strings to empty and all variants and interfaces to Unassigned, thus properly releasing any memory that was referenced by the long strings and variants.

Сам использую эту процедуру, для AnsiString работает корректно, память освобождается, никаких утечек.
PM MAIL   Вверх
Dom
Дата 4.4.2010, 21:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



А теперь по теме.
Может дело все же не в освобождении памяти из-под записей в дереве, если ручное "затирание" строк не устраняет утечек?
PM MAIL   Вверх
uwannadie
Дата 4.4.2010, 21:39 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


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

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



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


Эксперт
***


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

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



По теме и не по теме:
Dom, согласен, туплю. (по поводу высвобождения строк).
uwannadie, 
Dom, 
Дело действительно не в бобине smile Все-таки пришлось сделать тестовый проект, больно зацепила задачка.
В итоге - проблема в связках FindFirst>FindNext>FindClose процедуры FillTreeviewWithFiles. Если говорить точнее - то при окончании цикла по директориям не вызывался FindClose, а сразу шел FindFirst по файлам. Ну и + FindClose должен вызываться не всегда, а при успешном вызове FindFirst (гы, справка рулит smile  )

UPD: то ли лыжи не едут, то ли не пойму - утечки опять появились. Сейчас будем править...

Это сообщение отредактировал(а) kami - 4.4.2010, 21:54
PM MAIL WWW   Вверх
Dom
Дата 4.4.2010, 22:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



Опять же получается "не по теме".
Вот тоже собрал тестовый проект, но по другому случаю - на посмотреть как освобождаются данные из узлов.
Получил неожиданный результат. Процедура OnFreeNode вызывается только для тех узлов, которые были видны на форме. И следовательно память из-под узлов которые не были видимы не освобождается. Если прокрутить список узлов до конца, то при вызове Clear освобождаются все узлы, и никаких утечек нет.
Э-э-э, в чем подвох?
Могу приложить тестовый проект, если требуется.
PM MAIL   Вверх
Dom
Дата 4.4.2010, 22:29 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



Ага, заглянул в исходники. Чтобы вызвалась OnFreeNode должно выполнится условие
Код

[vsInitialized, vsInitialUserData] * Node.States <> []

Но при создании не все узлы получают vsInitialized.
А вот если после добавления всех узлов вызвать FullExpand, то память освобождается корректно без каких-либо дополнительных манипуляций. Т.е. инициализация происходит для всех узлов в этом случае.
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.0770 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


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

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