Форум: "Основная";
Текущий архив: 2003.07.14;
Скачать: [xml.tar.bz2];
ВнизОшибка записи в поток. Найти похожие ветки
← →
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;
Скачать: [xml.tar.bz2];
Память: 0.48 MB
Время: 0.009 c