byte [] и эффективно передается по ссылке - PullRequest
5 голосов
/ 31 января 2012

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

В двух словах, у меня есть цикл, который извлекает документы из базы данных.В настоящее время он извлекает по одному документу за раз, а затем обрабатывает документ.Документы могут варьироваться от менее чем мег до 400+ мег.(следовательно, почему я обрабатываю по одному).Ниже приведен псевдокод, и до того, как я его оптимизировал.

Итак, я делаю следующие шаги:

  1. Позвоните в базу данных, чтобы найти самую большуюразмер файла (а затем умножить его на 1,1)

    var maxDataSize = new BiztalkBinariesData().GetMaxFileSize();
    maxDataSize = (maxDataSize != null && maxDataSize > 0)
        ? (long)(maxDataSize * 1.1)
        : 0;
    var FileToProcess = new byte[maxDataSize];
    
  2. Затем я делаю еще один вызов базы данных, извлекая все документы (без данных) из базы данных и помещая их в IEnumerable.

    UnprocessedDocuments =
        claimDocumentData.Select(StatusCodes.CurrentStatus.WaitingToBeProcessed);
    foreach (var currentDocument in UnprocessDocuments)
    {
         // all of the following code goes here
    }
    
  3. Затем я заполняю свой массив байтов [] из внешнего источника:

    FileToProcess = new BiztalkBinariesData()
        .Get(currentDocument.SubmissionSetId, currentDocument.FullFileName);
    
  4. Вот вопрос.Было бы намного чище передать currentDocument (IClaimDocument) другим методам для обработки.Так что, если я установлю часть данных currentDocument в предварительно отформатированный массив, будет ли он использовать существующую ссылку?Или это создает новый массив в куче больших объектов?

    currentDocument.Data = FileToProcess;
    
  5. В конце цикла я бы очистил FileToProcess

    Array.Clear(FileToProcess, 0, FileToProcess.length);
    

Это было ясно?Если нет, я постараюсь почистить.

Ответы [ 5 ]

6 голосов
/ 31 января 2012

Шаг 1:

var FileToProcess = new byte[maxDataSize];

Шаг 3:

FileToProcess = new BiztalkBinariesData()
    .Get(currentDocument.SubmissionSetId, currentDocument.FullFileName);

Ваш шаг 1 совершенно не нужен, так как вы переопределяете массив на шаге 3 - вы создаете новый массив, вы не заполняете существующий массив - так что по сути шаг 1 просто создает больше работать на GC, который, если вы делаете это в быстром порядке (и если он не оптимизирован компилятором, что вполне возможно), может объяснить некоторую нагрузку на память, которую вы видите.

3 голосов
/ 31 января 2012

Массивы являются ссылочными типами, и поэтому вы будете передавать копию ссылки, а не копию самого массива.Это было бы верно только для типов значений .

Этот простой фрагмент иллюстрирует, как массивы ведут себя как ссылочные типы:

public void Test()
{    
    var intArray = new[] {1, 2, 3, 4};
    EditArray(intArray);
    Console.WriteLine(intArray[0].ToString()); //output will be 0
}

public void EditArray(int[] intArray)
{
    intArray[0] = 0;
}
2 голосов
/ 31 января 2012

Ваша проблема может заключаться в реализации и использовании класса "BiztalkBinariesData".

Я не уверен, как это реализовано, но я вижу, что вы каждый раз объявляете новый экземпляр

new BiztalkBinariesData()

О чем подумать ..

2 голосов
/ 31 января 2012

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

1 голос
/ 31 января 2012

У меня OutOfMemoryExceptions, и я чувствую, что это потому, что мы создаем слишком много байтов массива

Нет, это потому, что вы выделяете БОЛЬШИЕ массивы. Ограничьте их до 48 КБ или 64 КБ и «объедините» их с пользовательским контейнером. 64 КБ означает, что вы можете взять 2 старших байта индекса, чтобы определить используемый массив. Контейнер содержит массивы массивов. Обработка очень больших объектов приводит к разочарованию и невозможности выделить один большой массив позже.

...