![]() |
|
|
![]()
|
|
| OVT |
|
||||||
|
Новичок Профиль Группа: Участник Сообщений: 19 Регистрация: 29.8.2006 Репутация: нет Всего: нет |
Добрый день!
Есть приложение (delphi 6, Windows XP SP3), предназначенное для синхронизации данных в двух различных БД (MS SQL 2005 через ADO и Sybase 7 через BDE). Обработка данных происходит по зацикленному сценарию, состоящему из последовательного вызова нескольких процедур. Принцип работы каждой процедуры заключается в чтении данных с помощью TQuery в динамические массивы из каждой БД, сравнении прочитанных данных и, в зависимости от результатов сравнения, добавлении, удалении или обновлении данных в этих БД. Весь сценарий обработки вынесен в отдельный поток. На главной форме приложения отображается ход (TProgressBar) и результаты (TMemo, TChart) обработки данных. Кроме того, главная форма содержит несколько параметров (TEdit, TCheckBox), используемых при обработке данных в потоке. Все "общение" между рабочим потоком и потоком приложения происходит через Syncronize, т. е. ни к каким глобальным переменным или контролам главной формы рабочий поток на напрямую не обращается. Для рабочего потока в общем TDataModule созданы TDataBase и TADOConnection для подключения к соответствующим БД, а для TDataModule еще и отдельный TSession. Вроде, все рекоммендации, изложенные в статье Петровича http://forum.vingrad.ru/topic-60076.html (огромная благодарность автору!), мною учтены, программа работает, но наблюдается постоянный рост объема используемой памяти ~ 20MB за один цикл. Таким образом, через 50 - 60 циклов программа занимает около 1.2 GB и начинаются ошибки, в основном при обращении к MS SQL, типа "истек таймаут", "неверные параметры хранимой процедуры" и т. п. Подозревая наличие утечки памяти, пытался использовать FastMM4, но отчет показал наличие всего нескольких утечек, и то, похоже, не моих, по несколько десятков байт: 13 - 20 bytes: TObjectList x 3, Unknown x 3 21 - 36 bytes: TWinHelpViewer x 1 37 - 52 bytes: THelpManager x 1 Хотя с FastMM4 работаю впервые и, скорее всего, просто не умею им пользоваться. Некоторое время назад я написал аналогичное приложение, в котором не использовал потоки и ADO. Подобных фокусов с пожиранием памяти в нем я не наблюдал. Думаю, что собака порылась либо в потоке (видимо я упустил что-то важное для работы с БД), либо это связано с ADO, или тем, как я его использую в отдельном потоке. Не подскажете, где мой косяк? Исключительно с целью представления о структуре программы, привожу выдержки из кода:
Главная форма
Поток
Это сообщение отредактировал(а) OVT - 19.4.2010, 13:51 |
||||||
|
|||||||
| imageman |
|
|||
![]() Шустрый ![]() Профиль Группа: Участник Сообщений: 66 Регистрация: 30.9.2004 Репутация: нет Всего: 1 |
я бы (для начала) открывал доступ к БД из основного потока (например при нажатии на кнопку Старт) и не закрывал бы связь с БД на протяжении всего рабочего времени... Что-то мне подсказывает, что проблема может быть в частом отрытии-закрытии. Но у меня мало опыта.
Кстати, глобальные переменные я использую вовсю. Правда, как правило, значения глобальной переменной меняется в основном потоке, а считываются в дочерних. Как я понимаю на чтение никаких проблем быть не должно. (Да и запись пройдет нормально, только логика алгоритма может быть нарушена.) Это сообщение отредактировал(а) imageman - 29.4.2010, 17:17 |
|||
|
||||
| OVT |
|
|||
|
Новичок Профиль Группа: Участник Сообщений: 19 Регистрация: 29.8.2006 Репутация: нет Всего: нет |
На самом деле доступ к БД открывается один раз, когда стартует поток по нажатию на кнопку "Старт". Дальнейшая обработка крутится внутри Execute до тех пор, пока в основном потоке не будет нажата кнопка "Стоп".
У меня закралось подозрение, что я не правильно настраиваю (точнее оставляю по умолчанию все свойства) TADOQuery и TADOStoredProc. При подсчете количества записей в запросе (RecordCount) здорово увеличивается объем используемой памяти, гораздо больше, чем требуется для помещения в память всего результата запроса. После подсчета числа записей я аллокирую массив под данные - память расходуется, но в сотни раз меньше. Дальше, когда я начинаю последовательно читать записи и заносить данные в массив, память опять расходуется. При закрытии запроса (Active := False) память не освобождается полностью. Складывается такое ощущение, что память, израсходованная при подсчете числа записей, не освобождается. По диспетчеру задач очень сложно определить количество памяти, занимаемое приложением в тот или иной момент времени, для детального анализа и поиска утечки памяти. Если я правильно понимаю, то не существует функции, возвращающей объем памяти, занятый конкретным приложением. По крайней мере, я пока не нашел такой. |
|||
|
||||
![]()
|
| Правила форума "Delphi: Базы данных и репортинг" | |
|
|
Запрещено: 1. Публиковать ссылки на вскрытые компоненты 2. Обсуждать взлом компонентов и делиться вскрытыми компонентами Обязательно указание: 1. Базы данных (Paradox, Oracle и т.п.) 2. Способа доступа (ADO, BDE и т.д.)
FAQ раздела лежит здесь! Если Вам помогли и атмосфера форума Вам понравилась, то заходите к нам чаще! С уважением, Vit, Петрович. |
| 0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей) | |
| 0 Пользователей: | |
| « Предыдущая тема | Delphi: Базы данных и репортинг | Следующая тема » |
|
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |