Экспертная система Delphi.int.ru

Сообщество программистов
Общение, помощь, обмен опытом

Логин:
Пароль:
Регистрация | Забыли пароль?

Delphi.int.ru Expert

Другие разделы портала

Переход к вопросу:

#   

Статистика за сегодня:  


Лучшие эксперты

Подробнее »



Вопрос # 1 942

Раздел: Delphi » Прочее
/ вопрос открыт /

Здравствуйте, уважаемые эксперты!
Вот зашёл в тупик и не пойму в чём дело:
Имеется поток...
.... var b1: TBitmap....
while not Terminated do
begin
b1:=CaptureScreenRect(Rect1);// снимаю скриншот
b1.PixelFormat:=pf1Bit; // преобразую в ч/б
// далее обработка ....
b1:=CaptureScreenRect(Rect2);
b1.PixelFormat:=pf1Bit;
// далее обработка ....
b1:=CaptureScreenRect(Rect3);
b1.PixelFormat:=pf1Bit;
// далее обработка ....
b1.Free;
end;

И вот проблема, проходит примерно циклов 10 и ИМЕННО на первом b1.PixelFormat:=pf1Bit выкидывает ошибку о "нехватки памяти для обработки команды". В чём может быть проблема?
При чём когда я этот код кидаю в таймер, всё работает на "ура"...
Буду очень благодарен за оперативные советы ;)

Ice-Breaker Вопрос ожидает решения (принимаются ответы, доступен мини-форум)

Вопрос задал: Ice-Breaker (статус: Посетитель)
Вопрос отправлен: 27 сентября 2008, 16:17
Состояние вопроса: открыт, ответов: 1.

Ответ #1. Отвечает эксперт: Вадим К

Здравствуйте, Ice-Breaker!
Попробую напрячь свои телепатические возможности и угадать, что же там происходит. Если я правильно почитал мысли, то у Вас должна быть фунция вида

function CaptureScreenRect(ARect: TRect): TBitmap;
var
  ScreenDC: HDC;
begin
  Result := TBitmap.Create;
  with Result, ARect do
  begin
    Width := Right - Left;
    Height := Bottom - Top;
 
    ScreenDC := GetDC(0);
    try
      BitBlt(Canvas.Handle, 0, 0, Width, Height,
        ScreenDC, Left, Top, SRCCOPY);
    finally
      ReleaseDC(0, ScreenDC);
    end;
  end;
end;
Посмотрев внимательно на неё, понимаешь, что это тот же конструктор, только более "навороченный". Да, Ваш код может отличаться, но строка вида := TBitmap.Create; в нем обязана присутствовать, иначе работать вообще не будет.
Теперь смотрим внимательно на ваш код. Видим, что 3 раза вызывается конструктор (правда завуалировано) и один раз деструктор. То есть, налицо утечка памяти. Одна иттерация - 2 объекта. На 10 иттерациях - 20. По самым оптимистическим оценкам это как минимум 20 Мб. А память для потока на самом деле ограничена, не может он бездумно вызывать и занимать. Вот и натолкнулись. Вообще то при работе с потоками надо активно использовать Try - except, а то в противном случае можно хорошо схлопотать.
Почему же с таймерами не возникает такого? да возникнет, только чуть позже. просто тут память ограничена доступной, а это с учётом свопа - до 4 Гб - топать и топать. Ради эксперемента, можно запустить программу и посмотреть в диспетчере задач, как растёт потребление памяти.:)
Что же делать? ну как минимум надо освобождать память вызовами метода Free. Во вторых добавить хотя бы один глобальный Try except. Ведь многие исключения в потоках происходят "молча".

Ответ отправил: Вадим К (статус: Академик)
Время отправки: 27 сентября 2008, 17:25
Оценка за ответ: 5

Комментарий к оценке: ТОЧНО !!!! Блин ... ступил .... добавил диструкторов после обработок, вс нормально заработало ... Спасибо ...
P.S. А память, то утекает вс равно зараза ... по 4кб за цикл ... пошл дальше смотреть чего там забыл ещ...

Мини-форум вопроса

Мини-форум пуст.

Чтобы оставлять сообщения в мини-форумах, Вы должны авторизироваться на сайте.

Версия движка: 2.6+ (26.01.2011)
Текущее время: 22 февраля 2025, 11:32
Выполнено за 0.03 сек.