Форум: "Начинающим";
Текущий архив: 2010.03.07;
Скачать: [xml.tar.bz2];
ВнизTMemoryStream Найти похожие ветки
← →
serhiyiv © (2010-01-02 12:11) [0]Народ привет. Подскажите пожалуйста, нужно в MemoryStream загрузить много картинок что б потом считать и возможно было удалить нужную картинку из памяти. Нашел похожый пример но там было много ненужного, что я и убрал и в результате получилась такая "суть". Закинуть в память, удалить и считать получаеться, но проблема заключаеться в том, что если закидать картинки размером меньше 100 кб то при удалении память почему то не освобождаеться а при повторном добавлении размер используемой памяти увеличиваеться. (например добавим 5 картинок по 100кб, используемая память увеличиться, потом удалим все 5 штук из памяти но размер останеться тот же, потом опять добавим 5 штук и память возрастет). Такого не происходит если закидивать картинки размером больше где то 500 кб. Сколько память забрало при добавлении, столько и освобождаеться. Но все же немного памяти кудато утекает. Подскажите пожалуйста как можно исправить ниже приведенный код или может вы можете навести иной пример.
var
Items:TList;
...
Додаю:
var
MS: TMemoryStream;
Image: TBitmap;
begin
Image:= TBitmap.create;
Image.loadfromFile ("C:\444.bmp");
MS:= TMemoryStream.Create;
MS.Position:=0;
Image.SaveToStream(MS);
Items.Add(MS);
Image.Free;
end;
Удаляю
var
MS: TMemoryStream;
begin
MS:= TMemoryStream(Items[0]);
MS.Position:= 0;
MS.Clear;
Items.Delete(0);
end;
← →
Ганя (2010-01-02 13:15) [1]при удалении неплохо бы еще и разрушить сам мемори-стрим
← →
Юрий Зотов © (2010-01-02 13:19) [2]> Image := TBitmap.create;
> MS:= TMemoryStream.Create;
А где уничтожение этих объектов?
Вот Вы создали битмап и загрузили в него картинку, потом создали поток и эту картинку него скопировали, а поток добавили в список. Но ведь первоначальный-то битмап (оригинал) так и остался, его же никто не удалял. Это утечка номер раз.
Потом Вы чистите поток и удаляете его из списка - но сам-то объект при этом не удаляется, он так и остается в памяти. Это утечка номер два.
И совершенно непонятно, зачем нужен MemoryStream - ведь после LoadFromFile картинка уже и так хранится в памяти (в битмапе). Не лучше ли вместо списка потоков сделать список битмапов и тем самым избежать лишних операций и лишнего расхода памяти?
Посмотрите справку по TObjectList - очень может пригодиться.
← →
Ганя (2010-01-02 13:19) [3]Это раз.
Два:MS.Position:= 0;
MS.Clear;
этот код не нужен
Ну и третье: Контролировать корректность работы с памятью с помощью диспетчера задач - дело неверное, для этой цели существуют специальные средства типа FastMem :-)
← →
Ганя (2010-01-02 13:21) [4]
> Юрий Зотов © (02.01.10 13:19) [2]
> Но ведь первоначальный-то битмап (оригинал) так и остался,
> его же никто не удалял.
Удалил, в первом методе последней строчкой.
Другое дело, что без try-finally
← →
Юрий Зотов © (2010-01-02 13:21) [5]Сорри, не сразу заметил Image.Free.
Значит, утечка номер раз отменяется, но утечка номер два остается.
← →
Palladin © (2010-01-02 13:55) [6]не вижу никаких противопоказаний для использования TImageList и не вижу никаких спецефических условий в задаче для использования TMemoryStream
← →
antonn © (2010-01-02 14:12) [7]
> Не лучше ли вместо списка потоков сделать список битмапов
> и тем самым избежать лишних операций и лишнего расхода памяти?
>
ну tbitmap это объект gdi, в виндовс есть какие либо ограничения на них?
> Palladin © (02.01.10 13:55) [6]
>
> не вижу никаких противопоказаний для использования TImageList
к примеру разные размеры картинок, разная глубина цвета.
← →
serhiyiv © (2010-01-02 15:20) [8]В том то и дело что мне нужно загрузить много (1000 +) маленьких картинок куда-то (для того и используб поток) чтоб потом возможно было удалить не нужные и вставить новые. Картинки разных размеров но ширина = высоте квадрата в который они вписываються, по тому TImageList не подходит, хотя можно было бы добавить задний фон что б ширина = высоте, но при выводе прийдеться етот фон удалять, а ето не подходит.
> Не лучше ли вместо списка потоков сделать список битмапов
> и тем самым избежать лишних операций и лишнего расхода памяти?
>
Вот попробовал но память вобще не освобождаеться:
var
Items:TList;
...
Додаю:
var
Image: TBitmap;
begin
Image:= TBitmap.create;
Image.loadfromFile ("C:\444.bmp");
Items.Add(Image);
//Image.Free; не освобождаю ведь тогда картинка не сохраниться
end;
Рисую
var
Image: TBitmap;
begin
Image:= Items[0];
SDIAppForm.Canvas.Draw(0,0, Image);
end;
Удаляю наверно не правильно :)
var
Image: TBitmap;
begin
Image:= Items[0];
Image.Free;
Items.Delete(0);
end;
← →
antonn © (2010-01-02 16:04) [9]
> Вот попробовал но память вобще не освобождаеться:
чем память мониторится? если "Диспетчером процессов" то стоит включить отображение еще одного столбца - виртуальной памяти.
примерно для этих же целей делал когда то класс, коряво, но подпилить можно, вдруг пригодится:
http://desksoft.ru/index.php?forum=13&th=110
← →
serhiyiv © (2010-01-02 21:15) [10]Большое спасибо за помощь. В примере который я раньше видел сделано что то похожее но я его не очень то понял а теперь с вашим примером все намного понятнее. Спасибо. И немного не по теме но все же подскажите что быстрее, если рисовать не bmp а jpg:
------1------
var
gdiGraphics: TGPGraphics;
Img: TGPImage;
begin
gdiGraphics:=TGPGraphics.Create(SDIAppForm.Canvas.handle);
Img:=TGPImage.Create(Filename);
gdiGraphics.DrawImage(Img,0, 0, W, H);
Img.Free;
gdiGraphics.Free;
-----2-----
var
Img:TPicture;
begin
Img:=TPicture.Create;
Img.LoadFromFile("...");
SDIAppForm.Canvas.Draw(0,0, Img.graphic);
Img.Free;
Страницы: 1 вся ветка
Форум: "Начинающим";
Текущий архив: 2010.03.07;
Скачать: [xml.tar.bz2];
Память: 0.47 MB
Время: 0.007 c