Member 12352638 Ответов: 1

Outofmemory в потоке памяти исключений


Дело Все

Я получил исключение error OutOfMemory при записи данных байтового массива через MemoryStream.

Мой ПК-64bit
ОПЕРАТИВНАЯ ПАМЯТЬ - 4 ГБ
DataSize-750MB - 786432000

мой код :-

using (MemoryStream MemStream = new MemoryStream())
                    {
                        using (CryptoStream CryptoStream = new CryptoStream(MemStream, Encryptor, CryptoStreamMode.Write))
                        {
                            CryptoStream.Write(PlainTextBytes, 0, PlainTextBytes.Length);

                            //System.Buffer.BlockCopy(PlainTextBytes, 0, MemStream.ToArray(), 0, PlainTextBytes.Length);

                            CryptoStream.FlushFinalBlock();
                            CipherTextBytes = MemStream.ToArray();
                            MemStream.Close();
                            CryptoStream.Close();
                        }
                    }


Ошибка приближается :-
CryptoStream.Write(PlainTextBytes, 0, PlainTextBytes.Length);



OutOfMemoryException.


Любое решение, Пожалуйста, помогите.


Спасибо.

Что я уже пробовал:

Поток cryptostream.Запись (PlainTextBytes, 0, PlainTextBytes.Длина);

InbarBarkai

Как долго длится ваш текст?

Member 12352638

750 МБ

Mehdi Gholam

Убедитесь, что ваш процесс 64-битный, а не 32-битный.

Member 12352638

Процесс 64 битный

Philippe Mori

Если ваши данные большие, то вы должны обрабатывать их блоками. Вам следует избегать работы с данными размером более нескольких сотен мегабайт, если возможны альтернативные алгоритмы.

1 Ответов

Рейтинг:
11

Jochen Arndt

Здесь в CodeProject есть статья, которая объясняет, что происходит и что можно сделать: Замена MemoryStream[^].

Краткое объяснение своими словами:

Такие объекты, как MemoryStream изначально не знаю о размере требуемой памяти. Таким образом, они начнут с довольно небольшого объема выделенной памяти. Когда эта память будет израсходована, они выделят новый блок обычно вдвое большего размера, скопируют содержимое предыдущего блока и освободят его. При необходимости больших объемов памяти это может привести к исключениям из памяти по трем причинам:


  1. При перераспределении требуется больше памяти (старый размер * 3)
  2. Вновь выделенный блок должен быть смежным
  3. Для 32-битных приложений может быть достигнут предел в 2 ГБ

Чтобы объяснить это на вашем примере 750 МБ:
Предполагая, что поток на самом деле содержит 700 МБ, он попытается выделить 1400 МБ. Это не сработает, если нет свободного смежного блока такого размера. Имея в виду существующие 700 МБ, ваш поток фактически будет владеть более чем половиной вашей установленной памяти в то время.

[РЕДАКТИРОВАТЬ]
Если вы заранее знаете необходимый размер, вам следует использовать конструктор, который принимает вместимость аргумент. Это позволяет избежать многократного перераспределения и выделения неиспользуемой памяти, и вы получите немедленное исключение, если распределение не удастся.
[/РЕДАКТИРОВАТЬ]


Member 12352638

Спасибо Вам за повтор.

На самом деле это зависит от оперативной памяти или что?

Моей системе ОЗУ :- 4 ГБ
OS-64byte

Jochen Arndt

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

Но 32-битные приложения имеют ограничение в 2 ГБ на процесс (3 ГБ с дополнительной настройкой). Если у вас есть 32-битное приложение, вы либо превышаете этот предел (ваш процесс также имеет другую выделенную память), либо у вас нет свободных блоков смежной памяти.

Все это объясняется в статье по ссылке из моего ответа.

Вы также должны попробовать мое предложение заранее установить емкость. Это может решить вашу проблему. Если нет, то вы должны подумать о редизайне (например, используя метод из статьи CP).

Mehdi Gholam

Мои 5!