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

Программирование на Visual Basic, главный форум. Обсуждение тем программирования на VB 1—6.
Даже если вы плохо разбираетесь в VB и программировании вообще — тут вам помогут. В разумных пределах, конечно.
Правила форума
Темы, в которых будет сначала написано «что нужно сделать», а затем просьба «помогите», будут закрыты.
Читайте требования к создаваемым темам.
Me!
Новичок
Новичок
 
Сообщения: 35
Зарегистрирован: 05.08.2007 (Вс) 21:35

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

Сообщение Me! » 29.09.2007 (Сб) 12:05

Доброго времени суток, уважаемые гуру программирования!

В ходе написания некоторой программы выяснилось, что имеет место утечка памяти при использовании следующего кода:
Код: Выделить всё

Public Function GetInfoPtr&(ByVal tp&)
Dim mSize&, mPtr&, st&, mRS&
mSize = 4096
mPtr = VirtualAlloc(0, mSize, &H1000, 4)
ZwQuerySystemInformation tp, mPtr, mSize, mRS
VirtualFree mPtr, 0, &H4000
mSize = mRS
mPtr = VirtualAlloc(0, mSize, &H1000, 4)
ZwQuerySystemInformation tp, mPtr, mSize, mRS
GetInfoPtr = mPtr
End Function

Private Sub GetPIDs()
Dim ChPrc() As Long, Arr&, mPtr&, mPtr2&, hCnt&, j&, isin As Boolean
mPtr = GetInfoPtr(16)
mPtr2 = mPtr
RtlMoveMemory ByVal VarPtr(hCnt), ByVal mPtr, 4 'кол-во структур SYSTEM_HANDLE
mPtr = mPtr + 4
ReDim ChPrc(0)
For i = 1 To hCnt
  RtlMoveMemory ByVal VarPtr(Arr), ByVal mPtr, 4
  isin = False
  For j = 0 To UBound(ChPrc)
   If Arr = ChPrc(j) Then isin = True: Exit For ' проверяем, есть ли такой PID уже в массиве
  Next
  If Not isin Then
   ReDim Preserve ChPrc(UBound(ChPrc) + 1)
   ChPrc(UBound(ChPrc)) = Arr ' если нет - добавляем в массив новый элемент и присваиваем ему значение PID
  End If
  mPtr = mPtr + 16
Next
VirtualFree mPtr2, 0, &H4000
End Sub

эта процедура заполняет динамический массив ChPrc значениями PID, получаемыми из списка хендлов.

Надеюсь на Вашу помощь. Заранее спасибо!

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

Сообщение Хакер » 29.09.2007 (Сб) 12:28

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

Me!
Новичок
Новичок
 
Сообщения: 35
Зарегистрирован: 05.08.2007 (Вс) 21:35

Сообщение Me! » 29.09.2007 (Сб) 13:22

простой эксперимент с заменой вышеприведённого участка на EnumProcesses из PSAPI.dll

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

Сообщение Хакер » 29.09.2007 (Сб) 13:29

Me!
Я не понял, это сообщение - это ответ на мой вопрос или это вольный комментарий? Если первое, ты либо ты не понял вопроса, либо я нифига не понял. Причём тут EnumProcess?

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

Ptr1, Ptr2, lt, gt - что всё это?

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

Amed
Алфизик
Алфизик
 
Сообщения: 5346
Зарегистрирован: 09.03.2003 (Вс) 9:26

Сообщение Amed » 29.09.2007 (Сб) 13:41

Раз не надо - не разбирайся. Кто-то заставляет?

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

Сообщение Хакер » 29.09.2007 (Сб) 14:11

Amed
Желание помочь человеку заставляет.
—We separate their smiling faces from the rest of their body, Captain.
—That's right! We decapitate them.

Me!
Новичок
Новичок
 
Сообщения: 35
Зарегистрирован: 05.08.2007 (Вс) 21:35

Сообщение Me! » 29.09.2007 (Сб) 16:31

ок, сорри за код - пишу лишь бы мне было понятно. поправил немного:

Код: Выделить всё

Private Sub GetPIDs()
Dim dPID() As Long, dPID_inStruct as Long, mPtr as Long, mPtr2 as Long, hCnt as Long, i as Long, j as Long, isin As Boolean
mPtr = GetInfoPtr(16) ' заполняем буфер инфой о хкндлах и помещаем указатель на него в mPtr
mPtr2 = mPtr
RtlMoveMemory ByVal VarPtr(hCnt), ByVal mPtr, 4 ' в HCnt - кол-во структур SYSTEM_HANDLE
mPtr = mPtr + 4 ' переходим к массиву структур SYSTEM_HANDLE в полученном буфере
ReDim dPID(0)
For i = 1 To hCnt
  RtlMoveMemory ByVal VarPtr(dPID_inStruct), ByVal mPtr, 4 ' копируем PID процесса, владеющего данным хендлом
  isin = False
  For j = 0 To UBound(dPID)
   If dPID_inStruct = dPID(j) Then isin = True: Exit For ' проверяем, есть ли такой PID уже в массиве dPID()
  Next
  If Not isin Then
   ReDim Preserve dPID(UBound(dPID) + 1)
   dPID(UBound(dPID)) = dPID_inStruct ' если нет - добавляем в массив dPID() новый элемент и присваиваем ему значение PID
  End If
  mPtr = mPtr + 16 ' перемещаем указатель на следующую структуру SYSTEM_HANDLE
Next
VirtualFree mPtr2, 0, &H4000
End Sub


вот описание структур:

Код: Выделить всё
typedef struct SYSTEM_HANDLE {
long PID;
BYTE ObjTypeNum;
BYTE flags;
SHORT Handle;
long pObject;
long GrantedAccess;
} SYSTEM_HANDLE;

typedef struct SYSTEM_HANDLE_INFORMATION {
long uCount;
SYSTEM_HANDLE aSH [];
} SYSTEM_HANDLE_INFORMATION;


про EnumProcess:
если получать массив идентификаторов процессов с помощью указанной функции вместо приведённого кода - утечки памяти нет, следовательно, проблема как раз в этом коде. EnumProcess я привёл только для примера - первое, что пришло в голову для получения аналогичного результата.

Всё же надеюсь на Вашу помощь!
ЗЫ: сам вчера с температурой сидел, понимаю...
Последний раз редактировалось Me! 29.09.2007 (Сб) 16:34, всего редактировалось 1 раз.

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

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

Ещё раз: С чего ты вообще взял, что утечка памяти есть?
—We separate their smiling faces from the rest of their body, Captain.
—That's right! We decapitate them.

HiSER
Обычный пользователь
Обычный пользователь
Аватара пользователя
 
Сообщения: 88
Зарегистрирован: 04.07.2007 (Ср) 18:17

Сообщение HiSER » 29.09.2007 (Сб) 16:33

А функция VirtualFree как объявлена, случаем не так:
Код: Выделить всё
Public Declare Function VirtualFree Lib "kernel32" (ByVal lpAddress As Long, ByVal dwSize As Long, ByVal dwFreeType As Long) As Long

Если да, то память надо чистить так:
Код: Выделить всё
VirtualFree VarPtr(mPtr), 0, &H4000

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

Сообщение Хакер » 29.09.2007 (Сб) 16:36

HiSER
Ты написал бред. VarPtr там не нужен ни в коем случае. VarPtr(mPtr) вернёт адрес на стеке.

И ты попытаешься освободить пространство, выделенное под стек. Что приведёт к краху.
—We separate their smiling faces from the rest of their body, Captain.
—That's right! We decapitate them.

Me!
Новичок
Новичок
 
Сообщения: 35
Зарегистрирован: 05.08.2007 (Вс) 21:35

Сообщение Me! » 29.09.2007 (Сб) 16:37

2 Хакер
проверяю ProcessExplorer'ом Руссиновича кол-во занимаемой памяти после каждого выполнения приведённого кода. для сравнения - если им не пользоваться - утечки нет

2HiSER
нет, здесь ошибки нет

HiSER
Обычный пользователь
Обычный пользователь
Аватара пользователя
 
Сообщения: 88
Зарегистрирован: 04.07.2007 (Ср) 18:17

Сообщение HiSER » 29.09.2007 (Сб) 16:46

О блин, уже глючу... :?

Как декларированы у тебя функции?

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

Сообщение Хакер » 29.09.2007 (Сб) 16:56

Me!
Я не знаю и не видел ProcessExplorer от Русиновича. Но, например, виндовый таскман имеет такую особенность: после VirtualFree объём занимаемой памяти не уменьшается. Но зато следующие VirtualAlloc не вызывают роста "занимаемой памяти".

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

Me!
Новичок
Новичок
 
Сообщения: 35
Зарегистрирован: 05.08.2007 (Вс) 21:35

Сообщение Me! » 29.09.2007 (Сб) 19:19

Попробуй выполнить это в цикле. Если из-за при этом объём занимаемой памяти будет непрерывно расти - да, мемори лик.

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

ЗЫ: Process Explorer можно найти на http://sysinternals.com

tyomitch
Пользователь #1352
Пользователь #1352
Аватара пользователя
 
Сообщения: 12822
Зарегистрирован: 20.10.2002 (Вс) 17:02
Откуда: חיפה

Сообщение tyomitch » 30.09.2007 (Вс) 13:55

sysinternals.com уже давно редиректит на microsoft.com ;-)
Изображение

Me!
Новичок
Новичок
 
Сообщения: 35
Зарегистрирован: 05.08.2007 (Вс) 21:35

Сообщение Me! » 30.09.2007 (Вс) 14:18

tyomitch
зато sysinternals.com гораздо легчее запомнить и приятнее читать, чем microsoft.com/bla-bla-bla

хотелось бы и по теме что-нибудь услышать. есть идеи?

Me!
Новичок
Новичок
 
Сообщения: 35
Зарегистрирован: 05.08.2007 (Вс) 21:35

Сообщение Me! » 06.10.2007 (Сб) 20:39

Неужели так никто и не поможет?

|( () ( T |/| |(
Бывалый
Бывалый
Аватара пользователя
 
Сообщения: 211
Зарегистрирован: 01.10.2005 (Сб) 15:49

Сообщение |( () ( T |/| |( » 06.10.2007 (Сб) 21:29

А если закомментировать эту строчку.
Код: Выделить всё
ReDim Preserve ChPrc(UBound(ChPrc) + 1)

Всеровно утекает?
С=[::::::::::> ™ e398wallpapers.narod.ru

Me!
Новичок
Новичок
 
Сообщения: 35
Зарегистрирован: 05.08.2007 (Вс) 21:35

Сообщение Me! » 06.10.2007 (Сб) 23:45

если эту строку закомментировать, то алго не будет работать - ведь не будет массива на выходе! и, соответственно, код теряет смысл.

Proxy
Профессор VB наук
Профессор VB наук
Аватара пользователя
 
Сообщения: 2941
Зарегистрирован: 31.08.2007 (Пт) 4:41

Сообщение Proxy » 08.10.2007 (Пн) 11:20

У меня размер памяти до обращения к вышеуказанному событию ~ размеру памяти после обращения к вышеуказанному событию.

Me!
Новичок
Новичок
 
Сообщения: 35
Зарегистрирован: 05.08.2007 (Вс) 21:35

Сообщение Me! » 12.10.2007 (Пт) 19:47

О каком событии ты говоришь?


Вернуться в Visual Basic 1–6

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

Сейчас этот форум просматривают: Majestic-12 [Bot] и гости: 92

    TopList