Исключение из-за недостатка памяти, возникающее после повторного присвоения переменной вновь выделенному объекту - PullRequest
0 голосов
/ 08 февраля 2012

У меня есть программа, которая загружает файлы, они часто бывают большими, возможно, несколько сотен МБ. Это нормально, хотя компьютеры, на которых он работает, мощные.

Одновременно может быть загружен только один файл, и когда загружается новый, я переназначаю новый файл существующему объекту файла, например ::

myBigFile = new BigFile(fileName);

Я всегда предполагал, что предыдущий файл будет удален из памяти, но я обнаружил, что после загрузки нескольких файлов один за другим я часто получаю исключение «Недостаточно памяти».

Нужно ли вызывать GC.Collect() перед назначением нового файла моей файловой переменной? Я предполагал, что Windows очистит предыдущую память, когда она больше не будет использоваться?

EDIT

В дополнение к некоторым полезным комментариям я вернулся и реализовал IDisposable в соответствующих классах и подклассах, используя более или менее шаблон Microsoft:

Например, установить массивы классов в null, где у каждого подтипа также есть метод Dispose ():

public void Dispose()
{
    for (int i = 0; i < myArrayOfClassType.Length; i++)
    {
       myArrayOfClassType[i].Dispose();
    }

    myChannels = null;                

    GC.SuppressFinalize(this);
}

Затем, когда собирался загрузить новый файл, я сделал следующее:

if (myBigFile != null)
{
    //dispose any previous instance:
    myBigFile.Dispose();
    myBigFile = null;
    GC.Collect();
}

myBigFile = new BigFile(fileName);

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

Возможно ли, что они не удаляются сразу, а иногда это новый файл, который присутствует, когда происходит соответствующая очистка, и поэтому он частично удаляется сразу?

Любые идеи будут высоко оценены.

1 Ответ

0 голосов
/ 29 февраля 2012

Если массив, который выделяется при загрузке файла, достаточно велик, чтобы попасть в кучу больших объектов, то вы можете страдать от OutOfMemoryException от фрагментации. Если вы фрагментируете LOH до такой степени, что у вас есть 1,5 ГБ свободного места, но самое большое свободное пространство составляет 100 МБ, и вы выделите 101 МБ, вы получите исключение OutOfMemoryException.

Вы можете взглянуть на счетчики производительности, чтобы посмотреть размер LOH, чтобы дать вам представление, если это так.

...