Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

TMemoryStream


serhiyiv ©   (2010-01-02 12:11:00) 

Народ привет. Подскажите пожалуйста, нужно в 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;


serhiyiv   (2010-01-02 21:15:00) [1]

Большое спасибо за помощь. В примере который я раньше видел сделано что то похожее но я его не очень то понял а теперь с вашим примером все намного понятнее. Спасибо. И немного не по теме но все же подскажите что быстрее, если рисовать не 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;


antonn   (2010-01-02 16:04:00) [2]


> Вот попробовал но память вобще не освобождаеться:

чем память мониторится? если "Диспетчером процессов" то стоит включить отображение еще одного столбца - виртуальной памяти.

примерно для этих же целей делал когда то класс, коряво, но подпилить можно, вдруг пригодится:
http://desksoft.ru/index.php?forum=13&th=110


serhiyiv   (2010-01-02 15:20:00) [3]

В том то и дело что мне нужно загрузить много (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 14:12:00) [4]


> Не лучше ли вместо списка потоков сделать список битмапов
> и тем самым избежать лишних операций и лишнего расхода памяти?
>

ну tbitmap это объект gdi, в виндовс есть какие либо ограничения на них?


> Palladin ©   (02.01.10 13:55) [6]
>
> не вижу никаких противопоказаний для использования TImageList

к примеру разные размеры картинок, разная глубина цвета.


Palladin   (2010-01-02 13:55:00) [5]

не вижу никаких противопоказаний для использования TImageList и не вижу никаких спецефических условий в задаче для использования TMemoryStream


Ганя   (2010-01-02 13:21:00) [6]


> Юрий Зотов ©   (02.01.10 13:19) [2]


> Но ведь первоначальный-то битмап (оригинал) так и остался,
>  его же никто не удалял.


Удалил, в первом методе последней строчкой.
Другое дело, что без try-finally


Юрий Зотов   (2010-01-02 13:21:00) [7]

Сорри, не сразу заметил Image.Free.

Значит, утечка номер раз отменяется, но утечка номер два остается.


Юрий Зотов   (2010-01-02 13:19:00) [8]

> Image := TBitmap.create;
> MS:= TMemoryStream.Create;

А где уничтожение этих объектов?

Вот Вы создали битмап и загрузили в него картинку, потом создали поток и эту картинку него скопировали, а поток добавили в список. Но ведь первоначальный-то битмап (оригинал) так и остался, его же никто не удалял. Это утечка номер раз.

Потом Вы чистите поток и удаляете его из списка - но сам-то объект при этом не удаляется, он так и остается в памяти.  Это утечка номер два.

И совершенно непонятно, зачем нужен MemoryStream - ведь после LoadFromFile картинка уже и так хранится в памяти (в битмапе). Не лучше ли вместо списка потоков сделать список битмапов и тем самым избежать лишних операций и лишнего расхода памяти?

Посмотрите справку по TObjectList - очень может пригодиться.


Ганя   (2010-01-02 13:19:00) [9]

Это раз.
Два:
MS.Position:= 0;
MS.Clear;

этот код не нужен
Ну и третье: Контролировать корректность работы с памятью с помощью диспетчера задач - дело неверное, для этой цели существуют специальные средства типа FastMem :-)


Ганя   (2010-01-02 13:15:00) [10]

при удалении неплохо бы еще и разрушить сам мемори-стрим


Наверх

Титульная страница Поиск, карта сайта Написать письмо