|
Вопрос # 1 942/ вопрос открыт / |
|
Здравствуйте, уважаемые эксперты!
Вот зашёл в тупик и не пойму в чём дело:
Имеется поток...
.... 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 (статус: Посетитель)
Вопрос отправлен: 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кб за цикл ... пошл дальше смотреть чего там забыл ещ...
|
Мини-форум вопроса
Мини-форум пуст.
Чтобы оставлять сообщения в мини-форумах, Вы должны авторизироваться на сайте.
|