Утечка памяти в PB

Раздел посвящен программированию с использованием Power Basic.
ger_kar
Продвинутый гуру
Продвинутый гуру
Аватара пользователя
 
Сообщения: 1957
Зарегистрирован: 19.05.2011 (Чт) 19:23
Откуда: Кыргызстан, Иссык-Куль, г. Каракол

Утечка памяти в PB

Сообщение ger_kar » 02.04.2012 (Пн) 9:11

Проводил на днях опыты с целью определить скорость сканирования дерева каталогов с рекурсией в разных средах VB, PB, C++, но выявилось совершенно иное. Простейший алгоритм, который при реализации на VB не вызывает никаких проблем в PB приводит к утечке памяти.
Вот собственно в архиве исходник и скомпилированный exe.
Тест на утечку.rar
(26.66 Кб) Скачиваний: 284

Тестовая процедура рекурсивно обходит, просто перебирая файлы и папки на диске C: . При этом, если открыть диспетчер задач и наблюдать, сколько приложению выделяется памяти, то можно убедиться, что после каждого сканирования эта цифра растет. Проблема возникает из за того, что под динамические строки память выделяется всегда, а вот возвращается не всякий раз. Что касается структуры, то как показало исследование в отладчике, она полностью упаковывается в стек.
Вот такая лажа со строками.
Бороться и искать, найти и перепрятать

DarkMachine
Обычный пользователь
Обычный пользователь
Аватара пользователя
 
Сообщения: 51
Зарегистрирован: 24.02.2012 (Пт) 15:58

Re: Утечка памяти в PB

Сообщение DarkMachine » 02.04.2012 (Пн) 9:47

Надо вставить DIALOG DOEVENTS после команды обновления метки - дай системе отдохнуть :)
Лажы нет - это же рекурсия, при каждом вызове та передаешь параметр через стек, а когда вызываешь процедуру ещё раз, то освобождение стека не происходит. Стек освобождается когда ты выходишь из процедуры, а это происходит (в твоем случае) если найденный элемент - это файл.
Вообще в версии 10 сборщик мусора намного улучшен.

А где исходники на С++ и ВБ?

jangle
Википедик
Википедик
Аватара пользователя
 
Сообщения: 3013
Зарегистрирован: 03.06.2005 (Пт) 12:02
Откуда: Нидерланды

Re: Утечка памяти в PB

Сообщение jangle » 02.04.2012 (Пн) 10:01

Где собственно утечка памяти? В твоем коде при каждом вызове ScanDirectory в стеке размещаются все передаваемые параметры и локальные переменные. Поскольку рекурсивный вызов выполняется до окончания выполнения функции – размер стека увеличивается при каждом вызове функции.

ger_kar
Продвинутый гуру
Продвинутый гуру
Аватара пользователя
 
Сообщения: 1957
Зарегистрирован: 19.05.2011 (Чт) 19:23
Откуда: Кыргызстан, Иссык-Куль, г. Каракол

Re: Утечка памяти в PB

Сообщение ger_kar » 02.04.2012 (Пн) 10:47

DarkMachine писал(а):Лажы нет - это же рекурсия, при каждом вызове та передаешь параметр через стек, а когда вызываешь процедуру ещё раз, то освобождение стека не происходит. Стек освобождается когда ты выходишь из процедуры, а это происходит (в твоем случае) если найденный элемент - это файл.Вообще в версии 10 сборщик мусора намного улучшен.
Понятно, что рекурсия сама по себе потребляет большее количество стековой памяти, но потребление это прямо пропорционально количеству вызовов и пиковое потребление памяти, если таковых вызовов много, может быть весьма существенным. Здесь все совсем по другому, область памяти занятая под стек если и должна увеличится, то только первый раз, так чтобы разместить все вызовы. Но она растет раз за разом. Стек здесь не причем, ибо указатель стека ESP возвращается обратно.
DarkMachine писал(а):Стек освобождается когда ты выходишь из процедуры, а это происходит (в твоем случае) если найденный элемент - это файл.
Все правильно, если найдена папка, то для нее снова рекурсивно вызывается эта-же процедура и так происходит, пока не будет достигнута последняя вложенная папка, после чего в ней сканируются файлы если они там есть или же процедура заканчивается если там ничего нет. Т.е. она заканчивается в любом случае и происходит откат вызовов. Проблема именно в строковых переменных. И проблема эта вообще с рекурсией никак не связана, просто при рекурсии она хорошо проявляется визуально. Для каждой динамической строки ANSI вызывается SysAllocStringByteLen, освобождается память SysFreeString, но вот происходит это не всегда. С юникодовыми строками такая же проблема.
jangle писал(а):В твоем коде при каждом вызове ScanDirectory в стеке размещаются все передаваемые параметры и локальные переменные.
Не все. Динамические строки в стеке не размещаются, структуры да, динамические строки нет, в стеке размещается только указатель, в чем может убедится любой желающий. Стек здесь вообще не причем и рекурсия тоже. Тот-же алгоритм реализованный на VB к утечке памяти не приводит.

ЗЫ: Что касается исходников VB и C++, то выложу позже раз возник в них интерес, ибо я сейчас не дома.
Бороться и искать, найти и перепрятать

Хакер
Телепат
Телепат
Аватара пользователя
 
Сообщения: 16478
Зарегистрирован: 13.11.2005 (Вс) 2:43
Откуда: Казахстан, Петропавловск

Re: Утечка памяти в PB

Сообщение Хакер » 02.04.2012 (Пн) 10:55

ger_kar писал(а):тек здесь не причем, ибо указатель стека ESP возвращается обратно.

Да вот число закоммиченных страниц не уменьшается. Может в этом дело?
—We separate their smiling faces from the rest of their body, Captain.
—That's right! We decapitate them.

ger_kar
Продвинутый гуру
Продвинутый гуру
Аватара пользователя
 
Сообщения: 1957
Зарегистрирован: 19.05.2011 (Чт) 19:23
Откуда: Кыргызстан, Иссык-Куль, г. Каракол

Re: Утечка памяти в PB

Сообщение ger_kar » 02.04.2012 (Пн) 12:19

Хакер писал(а):Да вот число закоммиченных страниц не уменьшается. Может в этом дело?
Может и в этом, но это опять же проблемы PB, ибо за это отвечает компилятор. И видимо его сделали крововато, потому что он с этим надлежащим образом не справляется.
Бороться и искать, найти и перепрятать

Хакер
Телепат
Телепат
Аватара пользователя
 
Сообщения: 16478
Зарегистрирован: 13.11.2005 (Вс) 2:43
Откуда: Казахстан, Петропавловск

Re: Утечка памяти в PB

Сообщение Хакер » 02.04.2012 (Пн) 12:21

ger_kar писал(а):Может и в этом, но это опять же проблемы PB

Нет, это вообще не проблема ни компилятора, ни чья либо ещё.

Хотя я допускаю, что компилятор PB крив и кос :P
—We separate their smiling faces from the rest of their body, Captain.
—That's right! We decapitate them.

jangle
Википедик
Википедик
Аватара пользователя
 
Сообщения: 3013
Зарегистрирован: 03.06.2005 (Пт) 12:02
Откуда: Нидерланды

Re: Утечка памяти в PB

Сообщение jangle » 02.04.2012 (Пн) 12:26

ger_kar писал(а):Тот-же алгоритм реализованный на VB к утечке памяти не приводит.


Что-то в это слабо верится, подобный код будет приводит к расходу памяти на любом компиляторе.

ger_kar
Продвинутый гуру
Продвинутый гуру
Аватара пользователя
 
Сообщения: 1957
Зарегистрирован: 19.05.2011 (Чт) 19:23
Откуда: Кыргызстан, Иссык-Куль, г. Каракол

Re: Утечка памяти в PB

Сообщение ger_kar » 02.04.2012 (Пн) 12:57

Хакер писал(а):Нет, это вообще не проблема ни компилятора, ни чья либо ещё.
Почему, то же тогда тот же самый алгоритм, реализованный на нормально сделанном компиляторе VB работает корректно и не приводит ни к каким утечкам?
jangle писал(а):Что-то в это слабо верится, подобный код будет приводит к расходу памяти на любом компиляторе.
Причем здесь расход, когда речь идет именно об утечках. Расход это нормальное явление, а вот утечки нет. Расход это выделения памяти при необходимости, с последующим возвращением, когда такой необходимости более нет. Что собственно и демонстрирует тот-же самый алгоритм, реализованный на VB, когда в процессе сканирования идет расход памяти с последующим ее возвращением, когда сканирование окончено. В PB при каждом сканировании идет все новое и новое выделение памяти.
Бороться и искать, найти и перепрятать

Хакер
Телепат
Телепат
Аватара пользователя
 
Сообщения: 16478
Зарегистрирован: 13.11.2005 (Вс) 2:43
Откуда: Казахстан, Петропавловск

Re: Утечка памяти в PB

Сообщение Хакер » 02.04.2012 (Пн) 12:58

Первое свойство утечки — её невозможно однозначно определить как утечку.
А как ты определил, что у тебя есть утечка?
—We separate their smiling faces from the rest of their body, Captain.
—That's right! We decapitate them.

ger_kar
Продвинутый гуру
Продвинутый гуру
Аватара пользователя
 
Сообщения: 1957
Зарегистрирован: 19.05.2011 (Чт) 19:23
Откуда: Кыргызстан, Иссык-Куль, г. Каракол

Re: Утечка памяти в PB

Сообщение ger_kar » 02.04.2012 (Пн) 13:10

Хакер писал(а):А как ты определил, что у тебя есть утечка?
Да собственно случайно, в процессе тестирования однотипного алгоритма параллельно в VB и PB. Что-бы была ощутимая разница решил просканить все файлы на всех дисках. Ну и почему-то решил посмотреть, кто при этом отъест у системы больше памяти PB или VB. После каждого из запусков память потребляемая VB возвращалась на круги своя, в то время как у PB она продолжала расти и расти и после 20 сканирований зашкалила за 50 Мб.
Бороться и искать, найти и перепрятать

DarkMachine
Обычный пользователь
Обычный пользователь
Аватара пользователя
 
Сообщения: 51
Зарегистрирован: 24.02.2012 (Пт) 15:58

Re: Утечка памяти в PB

Сообщение DarkMachine » 02.04.2012 (Пн) 13:14

Не встаю за защиту языка, но этот алгоритм заезженный от и до. И если бы возникла утечка, то об этом давно уже знали.
У меня самого есть исходник с рекурсией, причем от более тяжеловат и делает массу вещей, но утечки не происходит.
Если проблема со строками (как ты указал), то попробуй еще так:
Код: Выделить всё
...
DIM ss AS STRING
...
      IF FindData.cFileName <> "."  AND  FindData.cFileName <> ".." THEN
          ss = sFullName
          ScanDirectory (ss)
      END IF   

jangle
Википедик
Википедик
Аватара пользователя
 
Сообщения: 3013
Зарегистрирован: 03.06.2005 (Пт) 12:02
Откуда: Нидерланды

Re: Утечка памяти в PB

Сообщение jangle » 02.04.2012 (Пн) 13:21

DarkMachine писал(а):Не встаю за защиту языка, но этот алгоритм заезженный от и до. И если бы возникла утечка, то об этом давно уже знали.


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

ger_kar
Продвинутый гуру
Продвинутый гуру
Аватара пользователя
 
Сообщения: 1957
Зарегистрирован: 19.05.2011 (Чт) 19:23
Откуда: Кыргызстан, Иссык-Куль, г. Каракол

Re: Утечка памяти в PB

Сообщение ger_kar » 02.04.2012 (Пн) 13:47

http://www.powerbasic.com/support/pbfor ... hp?t=49260
http://www.powerbasic.com/support/pbfor ... hp?t=49208

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

Ресурсия с динамическими строками? С простыми или юникодными? Насколько интенсивно используется? Дело в том, что если скажем просканировать флешку, то сразу в глаза ничего не бросается, это становится заметным этак с 10 примерно сканирования (на моей флешке у других может быть по другому). И в твоем алгоритме если этом механизм используется не часто и не очень интенсивно, можно ничего и не заметить, хотя возможно утечка есть и у тебя. Вот смотри простейший алгоритм (который мой), реализован вполне корректно (если нет, то где косяк?), но работает криво. То что это именно так легко убедится, можно сказать это факт!
То что касается предложенного варианта, то у меня была мысль, что может быть стоит попробовать промежуточные переменные, потому, что фактически они все равно создаются, но делая это явно, можно обойти проблему, но оказалось фиг вам.
jangle писал(а):Это точно, сам много раз использовал код для рекурсивного сканирования папок на PB, никогда проблем с утечками памяти не было.
Ну попробуй еще раз или попробуй просканировать тем, что ты делал раньше большой объем и увидишь результат.
Бороться и искать, найти и перепрятать

DarkMachine
Обычный пользователь
Обычный пользователь
Аватара пользователя
 
Сообщения: 51
Зарегистрирован: 24.02.2012 (Пт) 15:58

Re: Утечка памяти в PB

Сообщение DarkMachine » 02.04.2012 (Пн) 14:40

какая версия компилятора?

ger_kar
Продвинутый гуру
Продвинутый гуру
Аватара пользователя
 
Сообщения: 1957
Зарегистрирован: 19.05.2011 (Чт) 19:23
Откуда: Кыргызстан, Иссык-Куль, г. Каракол

Re: Утечка памяти в PB

Сообщение ger_kar » 03.04.2012 (Вт) 9:17

Вообще экспериментировал с 10.02, вчера скачал 10.03, что касается юникодовых строк, то в 10.03 ситуация стала значительно лучше, но с обычными ANSI все осталось без изменений.
Вот то же самый алгоритм реализованный на VB, никаких утечек нет и в помине.
RecursyScanVB.rar
Перезалил с нормальным модулем
(5.46 Кб) Скачиваний: 284

Нужно запустить тот и другой и сделать каждым по 10 сканированний, и как говорится - почувствуйте разницу.
Кстати я выяснил, что максимальная вложенность папок на диске C: у меня всего то ничего - 9 уровней, соответственно и рекурсия то всего ничего всего лишь 9 вложенных вызовов.
Последний раз редактировалось ger_kar 03.04.2012 (Вт) 12:03, всего редактировалось 1 раз.
Бороться и искать, найти и перепрятать

jangle
Википедик
Википедик
Аватара пользователя
 
Сообщения: 3013
Зарегистрирован: 03.06.2005 (Пт) 12:02
Откуда: Нидерланды

Re: Утечка памяти в PB

Сообщение jangle » 03.04.2012 (Вт) 9:24

ger_kar писал(а):Вообще экспериментировал с 10.02, вчера скачал 10.03, что касается юникодовых строк, то в 10.03 ситуация стала значительно лучше, но с обычными ANSI все осталось без изменений.
Вот то же самый алгоритм реализованный на VB, никаких утечек нет и в помине.
RecursyScanVB.rar

Нужно запустить тот и другой и сделать каждым по 10 сканированний, и как говорится - почувствуйте разницу.
Кстати я выяснил, что максимальная вложенность папок на диске C: у меня всего то ничего - 9 уровней, соответственно и рекурсия то всего ничего всего лишь 9 вложенных вызовов.


Исходник кривой, нет модуля с
Код: Выделить всё
ScanDirectory

ger_kar
Продвинутый гуру
Продвинутый гуру
Аватара пользователя
 
Сообщения: 1957
Зарегистрирован: 19.05.2011 (Чт) 19:23
Откуда: Кыргызстан, Иссык-Куль, г. Каракол

Re: Утечка памяти в PB

Сообщение ger_kar » 03.04.2012 (Вт) 12:05

Перезалил архив с нормальным модулем. Теперь все ОК!
Бороться и искать, найти и перепрятать

ger_kar
Продвинутый гуру
Продвинутый гуру
Аватара пользователя
 
Сообщения: 1957
Зарегистрирован: 19.05.2011 (Чт) 19:23
Откуда: Кыргызстан, Иссык-Куль, г. Каракол

Re: Утечка памяти в PB

Сообщение ger_kar » 03.04.2012 (Вт) 15:04

Ну что убедились? Или у кого-то еще есть сомнения?
DarkMachine, может это показать на официальном форуме и испросить, что же думает по этому поводу сам производитель?
Бороться и искать, найти и перепрятать

ger_kar
Продвинутый гуру
Продвинутый гуру
Аватара пользователя
 
Сообщения: 1957
Зарегистрирован: 19.05.2011 (Чт) 19:23
Откуда: Кыргызстан, Иссык-Куль, г. Каракол

Re: Утечка памяти в PB

Сообщение ger_kar » 03.04.2012 (Вт) 20:21

Вот еще один тест.
Чтобы исключить рекурсию вообще комментировал строку с рекурсивным вызовом напрочь.
Для того, что бы был видимый эффект просто вызывается процедура сканирования 1000 раз подряд.
А сканирование проводится на директории C:\Windows.
В тестировании как всегда приняли участие VB и PB, вот и архивчик в этими прожектами ;)
Test_VBorPB.rar
(32.7 Кб) Скачиваний: 275

Запустил оба два приложения и вот собственно наблюдения:
Начало.jpg
Вот что мы имеем непосредственно после запуска перед началом тестирования
Начало.jpg (41 Кб) Просмотров: 13220

Потом собственно тесты, первым идет в бой старый добрый VB
TestVB.jpg
Сначала потестируем проект VB.
TestVB.jpg (35.15 Кб) Просмотров: 13220

После первого запуска имеем небольшое увеличение выделенной памяти, далее после 10 и более запусков сканирования состояние памяти остается неизменным, все ОК!

Далее тестируем PB
TestPB.jpg
TestPB.jpg (36.26 Кб) Просмотров: 13220

После каждого запуска имеем постоянное приращение памяти.
Вот такой облом. АБЫДНО ДА?
Бороться и искать, найти и перепрятать

DarkMachine
Обычный пользователь
Обычный пользователь
Аватара пользователя
 
Сообщения: 51
Зарегистрирован: 24.02.2012 (Пт) 15:58

Re: Утечка памяти в PB

Сообщение DarkMachine » 03.04.2012 (Вт) 22:52

Проверил. "Утечка" была -- точнее это не утечка, а использование памяти. Начал с 1200 кб закончил около 7600 кб. Надо ещё учитывать тот факт, что ВБ6 использует свой рантайм, а таск манагер его невидит.
Вся работа со строками приходится на библиотеку, вызов процедур, ветвление, логика на основную программу. Так что мы видим часть айсберга :)

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

Код: Выделить всё
#COMPILE EXE "EnumFiles"
#REGISTER NONE
#DIM ALL
#INCLUDE "Win32Api.Inc"

DECLARE FUNCTION PathMatchSpec LIB "SHLWAPI.DLL" ALIAS "PathMatchSpecA"(pszFile AS ASCIIZ, pszSpec AS ASCIIZ) AS LONG

FUNCTION FileEnum(RootF AS WSTRING, File() AS WSTRING, Filter AS WSTRING) AS LONG

LOCAL  FileName    AS STRING, wFileName AS WSTRING, pFile, pFilter AS STRING
LOCAL  Looper      AS LONG
LOCAL  FolderCount AS DWORD
STATIC FileCount   AS DWORD
STATIC FolderDeep  AS DWORD

DIM FileDD AS DIRDATA

pFilter = Filter

INCR FolderDeep
DIM SubFolder(0 TO 0) AS WSTRING

IF ASC(Rootf, - 1) <> 92 THEN Rootf = Rootf & "\"
SubFolder(0) = Rootf
FileName = DIR$(SubFolder(0) & "*", %SUBDIR OR %SYSTEM OR %HIDDEN OR %ReadOnly, TO FileDD ) 'Get folder or file

IF LEN(FileDD.FileName) THEN
    DO
      IF (GETATTR(SubFolder(0) & FileDD.FileName) AND %SUBDIR) THEN 'It's a subfolder
        INCR FolderCount 'Keep track of how many subfolder
        REDIM PRESERVE SubFolder(0 TO FolderCount)
        SubFolder(FolderCount) = SubFolder(0) & FileDD.FileName & "\" '
     ELSE 'GetAttr told us that it is a file
       pFile = FileDD.FileName
       IF PathMatchSpec(BYVAL STRPTR(pFile), BYVAL STRPTR(pFilter)) THEN 'Check against Filter
         REDIM PRESERVE File(0 TO FileCount)
         File(FileCount) = SubFolder(0) & FileDD.FileName
         INCR FileCount
       END IF
     END IF
     FileName = DIR$(NEXT, TO FileDD )
   LOOP WHILE LEN(FileDD.FileName)
   DIR$ CLOSE

   FOR Looper = 1 TO FolderCount
     FileEnum SubFolder(Looper), File() , Filter
   NEXT
END IF

DECR FolderDeep
IF FolderDeep = 0 THEN
   FUNCTION = FileCount
   FileCount = 0 'Reset for subsequent call
END IF
END FUNCTION

FUNCTION PBMAIN()
DIM   File(0 TO 0) AS WSTRING
LOCAL RootFolder   AS WSTRING
LOCAL Filter       AS WSTRING
LOCAL FileCount    AS DWORD

RootFolder = "c:\"
Filter = "*.*"

FileCount = FileEnum(RootFolder, File(), Filter)

END FUNCTION


Хакер
Телепат
Телепат
Аватара пользователя
 
Сообщения: 16478
Зарегистрирован: 13.11.2005 (Вс) 2:43
Откуда: Казахстан, Петропавловск

Re: Утечка памяти в PB

Сообщение Хакер » 04.04.2012 (Ср) 7:33

DarkMachine писал(а):а таск манагер его невидит.

С чего бы ради? :?
—We separate their smiling faces from the rest of their body, Captain.
—That's right! We decapitate them.

jangle
Википедик
Википедик
Аватара пользователя
 
Сообщения: 3013
Зарегистрирован: 03.06.2005 (Пт) 12:02
Откуда: Нидерланды

Re: Утечка памяти в PB

Сообщение jangle » 04.04.2012 (Ср) 9:35

После каждого запуска имеем постоянное приращение памяти.


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

ger_kar
Продвинутый гуру
Продвинутый гуру
Аватара пользователя
 
Сообщения: 1957
Зарегистрирован: 19.05.2011 (Чт) 19:23
Откуда: Кыргызстан, Иссык-Куль, г. Каракол

Re: Утечка памяти в PB

Сообщение ger_kar » 04.04.2012 (Ср) 11:55

jangle писал(а):Меня это копейки что-то не особо волнуют, если расход и есть, то слишком незначительный.
А должны бы волновать. Потому что это не копейки, а потенциальная проблема, причем с моей точки зрения весьма серьезная. Меня например такие "мелочи" очень даже волнуют, потому, что маленькие утечки могут привести к большим проблемам.
DarkMachine писал(а):Проверил. "Утечка" была -- точнее это не утечка, а использование памяти. Начал с 1200 кб закончил около 7600 кб.
После этого и я решил провести тест с целью выяснить потолок. Для теста выбрал тот же тест, что и выложенном последнем архиве, несколько его изменив и внедрив в него вечный цикл, приступил к тестированию. Запустил тест и ушел принимать завтрак.
Придя через некоторое время увидел следующую картину
TestPB_2.jpg
TestPB_2.jpg (42.05 Кб) Просмотров: 13188

После моего 25 минутного отсутствия потребляемая приложением память перевалила за 100 мб.
Какое уж тут потребление, это 100% утечка.
За алгоритм поиска без рекурсии спасибо, но теперь мне уже охота докопаться до истины и выявить точную причину утечки, зная которую, можно либо ее устранить, путь и за счет лишнего кода или не применять какие либо алгоритмы вообще. Я думаю узнать истину всем будет и интересно и полезно.
Бороться и искать, найти и перепрятать

ger_kar
Продвинутый гуру
Продвинутый гуру
Аватара пользователя
 
Сообщения: 1957
Зарегистрирован: 19.05.2011 (Чт) 19:23
Откуда: Кыргызстан, Иссык-Куль, г. Каракол

Re: Утечка памяти в PB

Сообщение ger_kar » 04.04.2012 (Ср) 19:21

Вобщем нашел я причину и место утечки, и что самое хорошее в этой ситуации, так это то, что зная про это место утечки, этой утечки легко избежать. Детальная трассировка в отладчике выявила следующее:
При объявлении функции
Код: Выделить всё
Declare Function FindFirst Lib   "kernel32.dll" Alias "FindFirstFileW" _
(ByVal lpFileName     As WString, ByRef lpFindFileData As WIN32_FIND_DATAW) As Long

И последующем вызове объявленной функции
Код: Выделить всё
sTemp = swDirectory & "*"
hSearch   = FindFirst(sTemp, DirInfo)
Происходит следующее: Так как передача параметра объявлена ByVal, компилятор делает копию строки, получает указатель на эту копию и упаковывает его в стек. В дальнейшем вызывается фукция WinApi, после возврата из которой, процесс как ни в чем не бывало продолжает свое выполнение, при этом совершенно забывая, про существование копии строки в памяти и совершенно естественно, что благополучно про неё забыв, функцию SysFreeString для нею не вызывает. Таким образом строка так и остается висеть в памяти. И повторяясь раз за разом эта ситуация накапливает уйму висячих (по чем совершенно зря) в памяти строк, тем самым расходуя эту память снова и снова.
Потестил и VB, который в принципе делает то же самое, только в отличии от PB, не забывает о произведенной копии, и после вызова функции своевременно освобождает память не вызывая утечек.
Таким образом зная про это обстоятельство избежать утечки можно, но при этом надо строить вызов так, что-бы избежать образования копии. Таким образом если в объявлении, объявить передачу аргумента ByRef, а при вызове вызывать так ByVal StrPtr(sTemp), то безымянной копии не образуется, WinApi, получает указатель на существующую строку sTemp, про которую компилятор всегда помнит и не забывает вставить для неё вызов SysFreeString и таким образом все в ажуре :)
Бороться и искать, найти и перепрятать

Димитрий
Продвинутый пользователь
Продвинутый пользователь
 
Сообщения: 194
Зарегистрирован: 26.01.2005 (Ср) 22:47
Откуда: Волгоград

Re: Утечка памяти в PB

Сообщение Димитрий » 05.04.2012 (Чт) 7:24

Но это не повод, чтобы отказываться от PB.

Конечно не повод, но предупреждён - значит вооружён :D
Так как передача параметра объявлена ByVal

Значит ли это, что все функции будут себя вести также?
может это показать на официальном форуме

Будет очень правильно.

ger_kar
Продвинутый гуру
Продвинутый гуру
Аватара пользователя
 
Сообщения: 1957
Зарегистрирован: 19.05.2011 (Чт) 19:23
Откуда: Кыргызстан, Иссык-Куль, г. Каракол

Re: Утечка памяти в PB

Сообщение ger_kar » 05.04.2012 (Чт) 9:02

Димитрий писал(а):Значит ли это, что все функции будут себя вести также?
Это надо проверить, вчера времени на это уже не было. И опять же надо проверить поведение как при вызовах WinApi, так и внутренние меж процедурные вызовы. Придется проверять, чтобы точно знать что к чему...
Бороться и искать, найти и перепрятать


Вернуться в Power Basic

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 6

    TopList