Вопрос к профи! (Память)

Программирование на Visual Basic, главный форум. Обсуждение тем программирования на VB 1—6.
Даже если вы плохо разбираетесь в VB и программировании вообще — тут вам помогут. В разумных пределах, конечно.
Правила форума
Темы, в которых будет сначала написано «что нужно сделать», а затем просьба «помогите», будут закрыты.
Читайте требования к создаваемым темам.
Scuder
Постоялец
Постоялец
Аватара пользователя
 
Сообщения: 334
Зарегистрирован: 17.08.2002 (Сб) 13:18
Откуда: Moscow, Russia

Вопрос к профи! (Память)

Сообщение Scuder » 14.05.2004 (Пт) 10:50

Народ, возникла очень серьёзная проблема.. Всё усугубляется тем, что с ней, наверное, никто и не сталкивался.. Я очень надеюсь хотя бы на какие-нибудь умные мысли.. :-)

Вкратце: есть очень серьёзный проект, написаный для удалённого терминала. Осуществляются услуги по оплате услуг связи (каламбурчик :-) ), предоставлению информации о мобильных телефонах, заказ/покупка телефонов, контрактов и т.п. Естественно, в проекте используется большое количество картинок (фотографии телефонов, логотипы, кнопки и т.п.). Так вот, этот самый терминал, понятно, должен работать в круглосуточном режиме годами. В связи с чем и возникла проблема: случайно наткнулся на контрол SystemMonitor и сунул его на главную форму.. Показывает выделение виртуальной памяти под программу. И вот спустя всего лишь сутки на тестовом терминале количество выделяемой памяти увеличилось с ~96 Mb до ~120 Mb. Это означает, что меньше, чем через месяц, программа просто вылетит и любой желающий сможет полазить в интернете, поиграться с компьютером и т.д. То есть мне голову оторвут, если это произойдёт.. Принцип работы проекта примерно такой: есть главная форма, которая постоянно на экране, и на неё в определённом месте подгружаются все остальные. Эти остальные постоянно загружают разные картинки. При выгрузке каждой формы я пишу Unload Form и Set Form = Nothing. Так вот, есть серьёзные подозрения на то, что винда (2000) все эти картинки кэширует (свопит) в надежде на то, что они ещё понадобятся программе, но т.к. формы всегда закрываются и открываются заново, картинки загружаются и кэшируются виндой снова! Короче, думается мне, что она все загружаемые картинки, блин, хранит в кэше! В общем, я надеюсь, ситуация ясна.. Нужно как-то сказать винде, чтобы она моих картинок вообще не касалась, то есть не свопила, а грузила в оперативную память, либо чтобы после выгрузки формы очищался своп.. Кстати, после выгрузки всего приложения своп очищается нормально. Но это не выход - раз в сутки автоматически перезагружать программу..

Буду очень благодарен за любую полезную информацию по этому вопросу!

alibek
Большой Человек
Большой Человек
 
Сообщения: 14205
Зарегистрирован: 19.04.2002 (Пт) 11:40
Откуда: Russia

Сообщение alibek » 14.05.2004 (Пт) 11:02

Регулярная перезагрузка программы - вполне разумное решение.
Но можно попробовать все картинки загружать через API и выводить на форму BitBlt. Будет несколько неудобно (выводить еще ладно, но тебе придется еще и рефреш контроллировать), но зато управлять памятью (в той части, что относиться к загрузке/выгрузке картинок) будешь ты сам.
Lasciate ogni speranza, voi ch'entrate.

Scuder
Постоялец
Постоялец
Аватара пользователя
 
Сообщения: 334
Зарегистрирован: 17.08.2002 (Сб) 13:18
Откуда: Moscow, Russia

Сообщение Scuder » 14.05.2004 (Пт) 11:35

Блин, это ж геморрой какой.. У меня проект уже готов и оттестирован.. Переделывать все формы замучаюсь.. :-( Да и не пользовался я BitBlt никогда, не знаю с чем её есть.. APIGuide посмотрел - поплохело от его примера.. %-) К тому же, в некоторых формах объекты (те же самые пикчербоксы) размножаются (Load Picture(i)) в зависимости от параметров.. Сотни картинок.. :-( Кстати, имеет ли смысл сделать Unload Picture(i) или при закрытии формы они сами должны анлоадиться и очищать память? И вот ещё: загрузка картинки существует (Me.Picture1.Picture = LoadPicture ...), но почему не существует UnLoad Picture?

Вообще ерунда какая-то.. :-( Может вопрос не к коду относится? Может, к компилятору или вообще к Windows?

А нельзя программно своп почистить? Или запретить кэширование картинок?

Sebas
Неуловимый Джо
Неуловимый Джо
Аватара пользователя
 
Сообщения: 3626
Зарегистрирован: 12.02.2002 (Вт) 17:25
Откуда: столько наглости такие вопросы задавать

Сообщение Sebas » 14.05.2004 (Пт) 11:41

Спроектирована неправильно!
Проверь на циклические ссылки объекты...

У меня серверная часть без проблем работает целый год(80 клиентов 7 типов)
- Я никогда не понимал, почему они приходят ко мне чтобы умирать?

sebas<-@->mail.ru

Scuder
Постоялец
Постоялец
Аватара пользователя
 
Сообщения: 334
Зарегистрирован: 17.08.2002 (Сб) 13:18
Откуда: Moscow, Russia

Сообщение Scuder » 14.05.2004 (Пт) 11:53

И что, на серверной части постоянно картинки подгружаются?

У меня вообще уже складывается ощущение, что если загрузить Windows, отключив клаву и мышь, он всё равно через пару лет умрёт.. Только своей смертью. :?

sanches
El compa&#241;ero
El compa&#241;ero
 
Сообщения: 823
Зарегистрирован: 09.01.2003 (Чт) 3:58
Откуда: Р_О_С_С_И_Я ! (Питер)

Сообщение sanches » 14.05.2004 (Пт) 12:12

Кстати, если все-таки надумаешь переделывать, то задумайся про стандартный контрол, отображающий HTML страницы (MS Internet Controls). Все отчеты и т.п., содержащие картинки, генерируй в HTML код и отображай в контроле. За длительные периоды времени не помнится мне, что IE жрал дополнительные ресурсы.
Изображение

Scuder
Постоялец
Постоялец
Аватара пользователя
 
Сообщения: 334
Зарегистрирован: 17.08.2002 (Сб) 13:18
Откуда: Moscow, Russia

Сообщение Scuder » 14.05.2004 (Пт) 12:18

Я его использую для вывода информации о тарифных планах.. Но думается мне, что IE ещё больше ресурсов сожрёт.. Да и вообще, прикинь форму, на которой находится один WebBrowser. Из него при лоаде ещё штук 20 создаются. Для каждого контрола свой HTML код надо генерировать динамически, потому как картинка меняться может.. Не, я думаю винда ещё быстрее умрёт.. :-)

alibek
Большой Человек
Большой Человек
 
Сообщения: 14205
Зарегистрирован: 19.04.2002 (Пт) 11:40
Откуда: Russia

Сообщение alibek » 14.05.2004 (Пт) 12:46

UnloadPicture нет, есть Set Picture1.Picture = Nothing.
А нельзя ли заменить Picture на Image? И ресурсов будут кушать поменьше, и память пропадать перестанет.
Lasciate ogni speranza, voi ch'entrate.

Scuder
Постоялец
Постоялец
Аватара пользователя
 
Сообщения: 334
Зарегистрирован: 17.08.2002 (Сб) 13:18
Откуда: Moscow, Russia

Сообщение Scuder » 14.05.2004 (Пт) 14:14

2 alibek: Заменил, всё то же самое.. :-( Виндам, кажется по барабану что свопить - главное, чтобы графический образ был.. :-(
Попробую сделать везде Set Image1.Picture = Nothing..

codemaster
Постоялец
Постоялец
Аватара пользователя
 
Сообщения: 604
Зарегистрирован: 13.02.2004 (Пт) 13:35

Re: Вопрос к профи! (Память)

Сообщение codemaster » 15.05.2004 (Сб) 19:50

Scuder писал(а):При выгрузке каждой формы я пишу Unload Form и Set Form = Nothing. Так вот, есть серьёзные подозрения на то, что винда (2000) все эти картинки кэширует (свопит) в надежде на то, что они ещё понадобятся программе, но т.к. формы всегда закрываются и открываются заново, картинки загружаются и кэшируются виндой снова! Короче, думается мне, что она все загружаемые картинки, блин, хранит в кэше!



Unload Form и Set Form = Nothing это конечно хорошо
но ты уверен что формы корректно выгружаются?
Попробуй проверить это через Logging и обратные ссылки

P.S. Прога крутится на терминале под W2K?

Scuder
Постоялец
Постоялец
Аватара пользователя
 
Сообщения: 334
Зарегистрирован: 17.08.2002 (Сб) 13:18
Откуда: Moscow, Russia

Сообщение Scuder » 17.05.2004 (Пн) 9:53

Unload Form и Set Form = Nothing это конечно хорошо
но ты уверен что формы корректно выгружаются?


Нет, я скорее уверен в обратном.. :-( Исходя из того, что приложение в целом память за собой очищает..

Попробуй проверить это через Logging и обратные ссылки


А можно поподробнее и про первое, и про второе?

P.S. Прога крутится на терминале под W2K?


Угу.

Mikle
Изобретатель велосипедов
Изобретатель велосипедов
Аватара пользователя
 
Сообщения: 4160
Зарегистрирован: 25.03.2003 (Вт) 14:02
Откуда: Туапсе

Сообщение Mikle » 17.05.2004 (Пн) 16:41

Scuder
И вот спустя всего лишь сутки на тестовом терминале количество выделяемой памяти увеличилось с ~96 Mb до ~120 Mb. Это означает, что меньше, чем через месяц, программа просто вылетит

По-моему не означает. Попробуй заполни своп вручную или отключи вообще, и потестируй программу.

Scuder
Постоялец
Постоялец
Аватара пользователя
 
Сообщения: 334
Зарегистрирован: 17.08.2002 (Сб) 13:18
Откуда: Moscow, Russia

Сообщение Scuder » 17.05.2004 (Пн) 17:15

2 Mikle

Я уже писал об этом, в программе раньше периодически запускался рекламный ролик, так вот, примерно через 10 часов все приложения вылетали, а w2k писал, что-то типа "Виртуальная память заканчивается" и "Совсем закончилась".. Пришлось ролик запускать из отдельного EXE'шника, потому как та же самая история была - память после ролика не очищалась..

codemaster
Постоялец
Постоялец
Аватара пользователя
 
Сообщения: 604
Зарегистрирован: 13.02.2004 (Пт) 13:35

Сообщение codemaster » 17.05.2004 (Пн) 22:54

Scuder писал(а):
Попробуй проверить это через Logging и обратные ссылки


А можно поподробнее и про первое, и про второе?

P.S. Прога крутится на терминале под W2K?


Угу.



Обратные ссылки - Делать ссылки WithEvents в обратную сторону.
Старый трюк для тестирования выгруженных форм и классов и не только....

В одном из bas файлов:
Код: Выделить всё
Global Collector As New Collector



Класс
Код: Выделить всё
Класс Collector (можно сделать приватным приватный):
Option Explicit

Event Collect(AddTo As Collection)

' Можно сделать свойством по умолчанию
Public Property Get Collected() As Collection
    Dim Coll As Collection
    Set Coll = New Collection
    RaiseEvent Collect(Coll)
    Set Collected = Coll
End Property



Класс ChildClass (публичный)
Option Explicit

Private WithEvents Coll As Collector

Private Sub Class_Initialize()
Set Coll = Collector
End Sub

Private Sub Coll_Collect(AddTo As Collection)
AddTo.Add Me
End Sub



тестовый вариант
Код: Выделить всё
Sub main()
Dim A(0 To 10) As ChildClass
Dim i As Integer
For i = 0 To 4
    Set A(i) = New ChildClass
    Debug.Print Collector.Collected.Count
Next
End Sub



остальное по вкусу
что касается разрабоки на VB6 под TS есть много ньюансов
особенно при пользовании граф. контролов

P.S. таймеры на формах есть?

Scuder
Постоялец
Постоялец
Аватара пользователя
 
Сообщения: 334
Зарегистрирован: 17.08.2002 (Сб) 13:18
Откуда: Moscow, Russia

Сообщение Scuder » 18.05.2004 (Вт) 10:08

2 codemaster

Гм, может, конечно, я совсем тупой, но я не понимаю что делает этот код и зачем он нужен.. :-(

Старый трюк для тестирования выгруженных форм и классов и не только....


Опять же, насколько я понимаю, выгруженная форма - эта та форма, к которой нельзя обратиться.. Так ведь?

P.S. таймеры на формах есть?


Конечно. Как минимум по одному на каждой.. На главной - 3.

codemaster
Постоялец
Постоялец
Аватара пользователя
 
Сообщения: 604
Зарегистрирован: 13.02.2004 (Пт) 13:35

Сообщение codemaster » 18.05.2004 (Вт) 12:12

Scuder писал(а):Гм, может, конечно, я совсем тупой, но я не понимаю что делает этот код и зачем он нужен.. :-(


Позволяет тестировать загруженные формы , классы ....



Scuder писал(а):Конечно. Как минимум по одному на каждой.. На главной - 3.


а ты останавливаешь таймер перед тем как выгрузить форму? :wink:

Scuder
Постоялец
Постоялец
Аватара пользователя
 
Сообщения: 334
Зарегистрирован: 17.08.2002 (Сб) 13:18
Откуда: Moscow, Russia

Сообщение Scuder » 18.05.2004 (Вт) 13:07

а ты останавливаешь таймер перед тем как выгрузить форму?


Хочешь сказать, что он продолжает "тикать"? :-)

Ennor
Конструктивный критик
Конструктивный критик
 
Сообщения: 2504
Зарегистрирован: 18.12.2001 (Вт) 3:58
Откуда: Калуга -> Москва

Сообщение Ennor » 18.05.2004 (Вт) 15:30

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

Scuder
Постоялец
Постоялец
Аватара пользователя
 
Сообщения: 334
Зарегистрирован: 17.08.2002 (Сб) 13:18
Откуда: Moscow, Russia

Сообщение Scuder » 18.05.2004 (Вт) 15:32

Ну вроде бы сегодня не первое апреля.. :-)

Я просто первый раз слышу про то, таймеры ещё стопить нужно.. :-)
А как, кстати? Timer1 = False? Или Timer1.Enable = False? Или это одно и то же?

codemaster
Постоялец
Постоялец
Аватара пользователя
 
Сообщения: 604
Зарегистрирован: 13.02.2004 (Пт) 13:35

Сообщение codemaster » 18.05.2004 (Вт) 15:39

Scuder писал(а):
а ты останавливаешь таймер перед тем как выгрузить форму?


Хочешь сказать, что он продолжает "тикать"? :-)


Однозначно грабли !!!!!! см. tips от MSDN
:wink:


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

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

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

    TopList