Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Начинающим";
Текущий архив: 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.005 c
15-1261595337
ford
2009-12-23 22:08
2010.03.07
Помогите с алгоритмом


15-1261447784
xayam
2009-12-22 05:09
2010.03.07
Проект Россия 3


15-1257258721
Romkin
2009-11-03 17:32
2010.03.07
Конкурс на Исходниках. С призами


2-1261733510
2expres
2009-12-25 12:31
2010.03.07
Mediaplayer


2-1262677121
Андрей Пл
2010-01-05 10:38
2010.03.07
Остановить выполнение пророги в задонном месте до опред. события?





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский