Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2003.07.14;
Скачать: CL | DM;

Вниз

Ошибка записи в поток.   Найти похожие ветки 

 
NAlexey ©   (2003-07-01 11:15) [0]

Никак не могу найти причину возникновения ошибки "Out of memory while expanding string memory". Как это происходит: в цикле выполняется создание TMemoryStream, и запись в него, потом Free.
Приблизительно так:

var
P: TMyClass;

S := TMemoryStream.Create;
P.SaveToStream(S);
S.Free;

TMyClass.SaveToStream(Stream:TStream);
var
I: integer;
begin
I := FIndex;
Stream.Write(I, SizeOf(Integer));
inherited;
end;

Ну я думаю что приведение кода здесь даже лишне, потому как до определенного момента все нормально, при выполнении цикла память программы растет, и приблизительно на 30mb вываливается это сообщение в процедуре TCustomMemoryStream.Realloc. Помогите пожалуйста побороть это дело.


 
NAlexey ©   (2003-07-01 11:18) [1]

Неправильно привел текст ошибки, правильно так: "Out of memory while expanding memory stream".


 
Юрий Федоров ©   (2003-07-01 11:25) [2]

Ну так все же написано в тексте ошибки


 
NAlexey ©   (2003-07-01 11:39) [3]

Читать я умею, я не пойму откуда ноги растут у этой ошибки? оперативки у меня 256. программа занимает 30(ну по крайней мере так показывает профайлер), в чем дело? Или при очередном расширении памяти она превысила какую то границу?


 
Юрий Федоров ©   (2003-07-01 11:41) [4]

Если писать в FileStream, ошибки не будет ?


 
MBo ©   (2003-07-01 11:57) [5]

IMHO, возможно следующее - при каждом (или не каждом, но часто) добавлении происходит реаллокация буфера MemoryStream на новом месте (поскольу ранее выделенного блока памяти недостаточно). Менеджер памяти не сразу освобождает память, вот она и забивается


 
NAlexey ©   (2003-07-01 12:05) [6]

>MBo ©
Что можно посоветовать в этом случае? Можно ли воспользоваться чем другим вместо TMemoryStream?


 
Digitman ©   (2003-07-01 12:06) [7]


> NAlexey


оперативная память здесь ни при чем.
ты, видимо, не представляешь себе, как организована виртуальное адр.пр-во процесса.

"на огурцах" то, что ты наблюдаешь, выглядит примерно так :
отказ происходит, когда система по запросу приложения на реаллокацию памяти не может найти в ВАП процесса приложения затребованное кол-во СМЕЖНЫХ свободных страниц для размещения обновляемого содержимого потока.
Иными словами, вирт.памяти у процесса может быть и хватает, но она дефрагментирована настолько, что найти в ней смежный (непрерывный по виртуальной адресации) "кусок" подходящего для реаллокации размера не представляется возможным

а каков смысл оперативного хранения в потоке такого объема данных ? для чего тебе нужно иметь поток такого ьольшого размера, что ты с ним делать собираешься, если даже успешно сформируешь его ?

imho, скорей всего, тебе следует пересмотреть концепцию оперативного использования памяти приложения касаемо эфеективности и надежности использования поточных механизмов.


 
MBo ©   (2003-07-01 12:21) [8]

TMemoryStream.SetSize в начале не поможет?


 
NAlexey ©   (2003-07-01 12:23) [9]

>а каков смысл оперативного хранения в потоке такого объема данных
Я не храню в потоке большой объем данных, просто я создаю и уничтожаю TMemoryStream в цикле. И сдается мне, что проблема в этом.


 
Digitman ©   (2003-07-01 12:48) [10]

ни в жизнь не поверю , что

<начало цикла>
создание объекта-потока
уничтожение только что созданного объекта-потока
<конец цикла>

может вызвать исключение подобного рода)

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


 
NAlexey ©   (2003-07-01 13:36) [11]

>вероятность настолько мала, что разговаривать об этом просто смешно)
Ок. Согласен, я не прав, TMemoryStream сооздается и уничтожается корректно. Здесь выяснились другие обстоятельства, так что дело обстоит следующим образом: в цикле происходит создание объекта и TMemoryStream, в поток читаются какие либо данные, потом эти данные присваиваются объекту и сохраняются в StringList, приблизительно так:

var
Obj: TMyObj;
S: TMemoryStream;
P: TMyClass;
begin

. . .

Obj := TMyObj.Create;
S := TMemoryStream.Create;
P.SaveToStream(S);
GetMem(Obj.Value, S.Size);
S.Seek(0,soFromBeginning);
S.Read(NewP.Value^,S.Size);
S.Free;
TStringList.AddObject(Name, Obj);

. . .

end;

Насколько это меняет дело?


 
Serginio   (2003-07-01 14:19) [12]

Посмотри
http://www.1c.hippo.ru/cgi-bin/predownl.cgi?id=2019

Проблема MemoryStream с распределением непрерывной памяти.
Специально для этого сделал свой аналог основанный на динамическом массиве выделенных страниц памяти. 2 месяца без глюков.


 
Digitman ©   (2003-07-01 16:03) [13]


> Насколько это меняет дело?


Резко меняет !!
строчка

P.SaveToStream(S);

как раз и генерирует исключение.
приведи точный код метода SaveToStream
то, что ты приводил ранее, не может служить причиной нехватки памяти при реаллокации : запись 4-х байт - это далеко не 30 мб, о которых ты говоришь.


 
NAlexey ©   (2003-07-02 11:42) [14]

>Digitman ©
Спасибо за участие:) Проблема разрешилась.



Страницы: 1 вся ветка

Текущий архив: 2003.07.14;
Скачать: CL | DM;

Наверх




Память: 0.5 MB
Время: 0.013 c
3-44569
RNZ
2003-06-20 12:06
2003.07.14
Как упаковать базу mdb (Microsoft Access Database) ?


6-44793
zom
2003-05-06 13:28
2003.07.14
Определение IP по имени компа (программно)


1-44764
INCOGNITO
2003-07-02 00:43
2003.07.14
ReadOnly Files


4-44940
Юлия
2003-05-12 10:55
2003.07.14
Как поменять заголовок окна чужого приложения?


1-44691
ss300
2003-06-29 17:02
2003.07.14
Выбрать из ста 20 случайных неповторяющихся чисел