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

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

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

Сообщение visitor » 08.10.2008 (Ср) 2:02

Вопрос уже открывался тут, но вразумительного ответа я так и не нашел.
Имею приличную по объемам программу. При открытии/закрытии определенного типа форм происходит заметное выжирание памяти (чуть ли не мегабайт на одно открытие)
Форма работает с данными из БД, получает рекордсет, имеет в себе достаточно много контролов, в общем грузиться не мгновенно и выделение памяти в 1 МБ под нее абсолютно оправдано.
Unload отрабатывает, по идее форма должна выгрузиться.
Вот только вопрос , почему ресурсы не освобождаются при закрытии формы?

Сюда же напишу связанный подвопрос: VB.Forms.Count хранит количество видимых или загруженных форм ?.. во всяком случае, VB.Forms.Count тоже сигнализирует о том, что формы выгружаются.

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


[ДОБАВЛЕНО]
Проверил в тестовом проекте, размещая некоторые левые контролы на форме происходит утечка .
Открываю и закрываю форму в цикле, форма грузится с каждым разом все медленнее.

Ума не приложу. Я полагал, что контролы должны умирать вместе с формой-контейнером.
Повторюсь, проект абсолютно чист, в нем только MDI парент, MDI чилд и на чилде пара контролов...
Извечный вопрос: что делать?

Viper
Артефакт VBStreets
Артефакт VBStreets
Аватара пользователя
 
Сообщения: 4394
Зарегистрирован: 12.04.2005 (Вт) 17:50
Откуда: Н.Новгород

Re: VB6. Утечка памяти

Сообщение Viper » 08.10.2008 (Ср) 7:03

Что делать? Освобождать и удалять все что можно освободить и удалить. Но специфика работы менеджера памяти Windows не гарантирует мгновенного освобождения памяти. Как то так.
Весь мир матрица, а мы в нем потоки байтов!

Antonariy
Повелитель Internet Explorer
Повелитель Internet Explorer
Аватара пользователя
 
Сообщения: 4824
Зарегистрирован: 28.04.2005 (Чт) 14:33
Откуда: Мимо проходил

Re: VB6. Утечка памяти

Сообщение Antonariy » 08.10.2008 (Ср) 9:52

А еще есть подозрение на утечки в юзерконтролах присущие им как VB-классу, а не конкретной реализации. Попробуй оформить их в ocx и сравнить расход до и после.
Лучший способ понять что-то самому — объяснить это другому.

visitor
Новичок
Новичок
 
Сообщения: 25
Зарегистрирован: 08.10.2008 (Ср) 1:52

Re: VB6. Утечка памяти

Сообщение visitor » 08.10.2008 (Ср) 14:37

Viper писал(а):Что делать? Освобождать и удалять все что можно освободить и удалить. Но специфика работы менеджера памяти Windows не гарантирует мгновенного освобождения памяти. Как то так.

Освобождаю все что можно.
Я же отписал, что сделал тестовый проект - пустой, голый, из кода - только цикл
From1.Show
Unload From1
и все...

Antonariy писал(а):А еще есть подозрение на утечки в юзерконтролах присущие им как VB-классу, а не конкретной реализации. Попробуй оформить их в ocx и сравнить расход до и после.

Не совсем понял, до и после чего ?
Сейчас они у меня в отдельном проекте...

Контрол явно мешает выгрузке формы контейнера. Чем именно он мешает - понять не могу
Вообще, может быть кто знает что НЕ нужно писать в UserControl ? :)

ANDLL
Великий гастроном
Великий гастроном
Аватара пользователя
 
Сообщения: 3450
Зарегистрирован: 29.06.2003 (Вс) 18:55

Re: VB6. Утечка памяти

Сообщение ANDLL » 08.10.2008 (Ср) 15:24

Просто посмотри, происходит ли у тебя Form-terminate
если происходит, значит утечка в другом месте, а форма точно уничтожается. Если не происходит... Значит твой контрол какимто образом плодит ссылку на форму
Гастрономия - наука о пище, о ее приготовлении, употреблении, переварении и испражнении.
Блог

visitor
Новичок
Новичок
 
Сообщения: 25
Зарегистрирован: 08.10.2008 (Ср) 1:52

Re: VB6. Утечка памяти

Сообщение visitor » 08.10.2008 (Ср) 15:46

ANDLL писал(а):Просто посмотри, происходит ли у тебя Form-terminate
если происходит, значит утечка в другом месте, а форма точно уничтожается. Если не происходит... Значит твой контрол какимто образом плодит ссылку на форму

Спасибо за совет, кое-какие мысли появились.. но ситуация не особо прояснилась.
Terminate формы вызывается, а вот Terminate UserControl'а , что лежит на этой форме - нет..как такое может быть?

Viper
Артефакт VBStreets
Артефакт VBStreets
Аватара пользователя
 
Сообщения: 4394
Зарегистрирован: 12.04.2005 (Вт) 17:50
Откуда: Н.Новгород

Re: VB6. Утечка памяти

Сообщение Viper » 08.10.2008 (Ср) 16:15

visitor писал(а):Terminate формы вызывается, а вот Terminate UserControl'а , что лежит на этой форме - нет..как такое может быть?
Значит где-то есть на него действующие ссылки.
Весь мир матрица, а мы в нем потоки байтов!

visitor
Новичок
Новичок
 
Сообщения: 25
Зарегистрирован: 08.10.2008 (Ср) 1:52

Re: VB6. Утечка памяти

Сообщение visitor » 08.10.2008 (Ср) 17:39

Viper писал(а):
visitor писал(а):Terminate формы вызывается, а вот Terminate UserControl'а , что лежит на этой форме - нет..как такое может быть?
Значит где-то есть на него действующие ссылки.

Нет ссылок. повторяю, проект голый. вот что есть
Код: Выделить всё
Option Explicit
  Dim x As frmTest1

Private Sub Timer1_Timer()
  Static c As Long
  If c = 0 Then
    Set x = New frmTest1
    x.Show
    c = 1
  ElseIf c = 1 Then
    Unload x
    Set x = Nothing
    c = 0
  End If
End Sub

в frmTest1 только контрол на форме и все.
выгрузка или невыгрузка определяется только контролом... чем именно - понять не могу

ANDLL
Великий гастроном
Великий гастроном
Аватара пользователя
 
Сообщения: 3450
Зарегистрирован: 29.06.2003 (Вс) 18:55

Re: VB6. Утечка памяти

Сообщение ANDLL » 08.10.2008 (Ср) 18:02

visitor писал(а):
Viper писал(а):
visitor писал(а):Terminate формы вызывается, а вот Terminate UserControl'а , что лежит на этой форме - нет..как такое может быть?
Значит где-то есть на него действующие ссылки.

Нет ссылок. повторяю, проект голый. вот что есть
Код: Выделить всё
Option Explicit
  Dim x As frmTest1

Private Sub Timer1_Timer()
  Static c As Long
  If c = 0 Then
    Set x = New frmTest1
    x.Show
    c = 1
  ElseIf c = 1 Then
    Unload x
    Set x = Nothing
    c = 0
  End If
End Sub

в frmTest1 только контрол на форме и все.
выгрузка или невыгрузка определяется только контролом... чем именно - понять не могу

А сам код контрола увидеть можно?
Гастрономия - наука о пище, о ее приготовлении, употреблении, переварении и испражнении.
Блог

visitor
Новичок
Новичок
 
Сообщения: 25
Зарегистрирован: 08.10.2008 (Ср) 1:52

Re: VB6. Утечка памяти

Сообщение visitor » 08.10.2008 (Ср) 18:07

ANDLL писал(а):А сам код контрола увидеть можно?


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

[ОТРЕДАКТИРОВАНО]
Отредактировал код, т.к. нашел причину такого неподобства ))
UserControl
Код: Выделить всё
'--------------------------------------------
Option Explicit
  Private mActiveCtl As Object
'--------------------------------------------
Public Sub Destroy()
  Set mActiveCtl = Nothing
End Sub
'--------------------------------------------
Private Sub UserControl_Terminate()
  Debug.Print "Ctl_1 TerminateXX"
End Sub
'--------------------------------------------
'Функция присваивает локальной (!) переменной ссылку на содержащийся в контроле объект UI (Текст бокс)
'Ссылка не выходит за пределы кода контрола, никуда больше не передается
Public Function SomeFunction(ByVal SomeParam As Long)
  Select Case SomeParam
    Case 1:
      Set mActiveCtl = mInternalTextBox
    '......
  End Select
End Function
'--------------------------------------------


Далее код формы (Вариант 1)
Код: Выделить всё
'...........
'somewhere
UserControlInstance.SomeFunction(1)
'...........


В таком случае контрол не выгружается, Terminate не происходит

код формы (Вариант 2)
Код: Выделить всё
'...........
'somewhere
UserControlInstance.SomeFunction(1)
'...........
Sub Form_Unload(Cancel)
  UserControlInstance.Destroy()
End Sub
'...........

При таком подходе контрол выгружается.

visitor
Новичок
Новичок
 
Сообщения: 25
Зарегистрирован: 08.10.2008 (Ср) 1:52

Re: VB6. Утечка памяти

Сообщение visitor » 09.10.2008 (Чт) 2:36

Итак, у меня возникает 2 вопроса:

1)Почему ссылка на объект остается жить? 100% проверено - за пределы UserControl она не выходит, что видно из примера. Должна умереть вместе с контролом ? но контрол-то не умирает, пока она жива )

2)В каком именно месте (Событии) в UserControl в таком случае делать очистку ? .. как видно, вызывать извне .Destroy() крайне неудобно, непрактично и неправильно.
:alien:

Viper
Артефакт VBStreets
Артефакт VBStreets
Аватара пользователя
 
Сообщения: 4394
Зарегистрирован: 12.04.2005 (Вт) 17:50
Откуда: Н.Новгород

Re: VB6. Утечка памяти

Сообщение Viper » 09.10.2008 (Чт) 7:06

visitor, прицепи сюда тестовую версию проекта, поковыряемся.
З.Ы. В приложенном проекте лишнее убрать, нужное оставить! :)
Весь мир матрица, а мы в нем потоки байтов!

visitor
Новичок
Новичок
 
Сообщения: 25
Зарегистрирован: 08.10.2008 (Ср) 1:52

Re: VB6. Утечка памяти

Сообщение visitor » 09.10.2008 (Чт) 8:31

Viper писал(а):visitor, прицепи сюда тестовую версию проекта, поковыряемся.
З.Ы. В приложенном проекте лишнее убрать, нужное оставить! :)

Да что уж там, набросал тестовый проект с нуля.. ничего лишнего :)
Group.rar
Контрол
(3.41 Кб) Скачиваний: 40

Antonariy
Повелитель Internet Explorer
Повелитель Internet Explorer
Аватара пользователя
 
Сообщения: 4824
Зарегистрирован: 28.04.2005 (Чт) 14:33
Откуда: Мимо проходил

Re: VB6. Утечка памяти

Сообщение Antonariy » 09.10.2008 (Чт) 8:50

Все правильно. У тебя юзерконтрол содержит ссылку на свой же (зачем???) контрол, который не может уничтожиться пока эта ссылка цела. А раз не все субконтролы уничтожены, значит не может уничтожиться сам юзерконтрол.
Лучший способ понять что-то самому — объяснить это другому.

visitor
Новичок
Новичок
 
Сообщения: 25
Зарегистрирован: 08.10.2008 (Ср) 1:52

Re: VB6. Утечка памяти

Сообщение visitor » 09.10.2008 (Чт) 9:05

[ОТРЕДАКТИРОВАНО]

Antonariy писал(а):Все правильно. У тебя юзерконтрол содержит ссылку на свой же (зачем???) контрол, который не может уничтожиться пока эта ссылка цела. А раз не все субконтролы уничтожены, значит не может уничтожиться сам юзерконтрол.

что правильно :) я уже понял.. хотя и не совсем правильно..
Случай 1)
форма содержит контрол.
контрол не выгружается?-Да.
Форма Terminate-Да
Случай 2)
Контрол содержит субконтрол
субконтрол не выгружается?-Да (на него есть живые ссылки)
Контрол Terminate-Нет
--какие-то непонятки все-же есть

вопрос зачем ?? используем прелести позднего связывания и общного программирования, не побоюсь этого слова - полиморфизма, дабы код был наглядным
Код: Выделить всё
Dim O as object
'----
o.Appearance = 0

удобно и работает вне зависимости от того, на какой именно конечный объект ссылается (о)

А вопрос-то остался.. где то место(событие), чтоб ссылку освободить ? :) или.. как ее освободить правильно?

[ДОБАВЛЕНО]
я уж тут ночью написал аля- микросборщик мусора :cyclops:
добавляю в него экземпляры контролов (из самих же контролов) и по таймеру проверяю, не умер ли контейнер контрола..если умер - вызываю заранее определенную функцию освобождения ссылок... но это такой же выход как "пить пепси через клизму" ). неудобно, негибко, тормозит.. и не нравится эстетически..
И объективных проблем достаточно, например, как проверить, умер ли контейнер контрола ?
я использую IsWindow(ContainerHWND), что само по себе не дает никаких гарантий... альтернатива - расплодить ссылку на контейнер - еще запутаннее схема выходит..
У кого какие мысли ?
Заране спасибо
------

Antonariy
Повелитель Internet Explorer
Повелитель Internet Explorer
Аватара пользователя
 
Сообщения: 4824
Зарегистрирован: 28.04.2005 (Чт) 14:33
Откуда: Мимо проходил

Re: VB6. Утечка памяти

Сообщение Antonariy » 09.10.2008 (Чт) 15:30

Случай 1)
форма содержит контрол.
контрол не выгружается?-Да.
Форма Terminate-Да
Если "Terminate-Да", следовательно контрол выгрузился.
какие-то непонятки все-же есть
Не понятно, что не понятно…
используем прелести позднего связывания и общного программирования, не побоюсь этого слова - полиморфизма, дабы код был наглядным
Реализация не фонтан. Лучше напиши функцию, которая будет возвращать ссылку когда надо, не держи ее постоянно.
где то место(событие), чтоб ссылку освободить ?
При наличии циклических ссылок таких мест нет. Только самопальным "сборщиком"-dispose.
Лучший способ понять что-то самому — объяснить это другому.

visitor
Новичок
Новичок
 
Сообщения: 25
Зарегистрирован: 08.10.2008 (Ср) 1:52

Re: VB6. Утечка памяти

Сообщение visitor » 10.10.2008 (Пт) 2:34

Antonariy писал(а):Если "Terminate-Да", следовательно контрол выгрузился.
Не понятно, что не понятно…

В моем прикрепленном проекте именно так. Форма -Terminate - Да, а контрол-нет.
Реализация не фонтан. Лучше напиши функцию, которая будет возвращать ссылку когда надо, не держи ее постоянно.


ВОО!!!! Идея! :idea: как щас модно говорить?? респект и уважуха! (?)
ПИВО СРОЧНОЙ АВИАПОЧТОЙ!!! с меня.. с меня.. черт, что на форуме с меня может быть? как минимум ОГРОМНОЕ СПАСИБО!
я так затупил что уже голова болела 5-й день.. причем в прямом смысле!
Вот не поленился ж подумать человек! :D



Всем спасибо за ответы!

PS:
а про Terminate контролов и формы все же интересно, на будущее. чтоб знать как не надо.. может еще попостимся в теме ?


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

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

Сейчас этот форум просматривают: AhrefsBot, Google-бот, Yandex-бот и гости: 13

    TopList