byte []并通过引用有效传递

Cyf*_*r13 5 c# asp.net bytearray out-of-memory c#-3.0

因此,这与处理大对象堆并尝试最小化实例化byte []的次数有关.基本上,我有OutOfMemoryExceptions,我觉得这是因为我们实例化了太多的字节数组.当我们处理几个文件时,程序工作正常,但它需要扩展,目前它不能.

简而言之,我有一个从数据库中提取文档的循环.目前,它一次拉一个文档然后处理文档.文件的范围可以从小于1兆欧卡到400欧元不等.(因此我为什么一次处理一个).以下是伪代码,在我进行优化之前.

所以我正在做的步骤是:

  1. 调用数据库以查找最大文件大小(然后将其乘以1.1)

    var maxDataSize = new BiztalkBinariesData().GetMaxFileSize();
    maxDataSize = (maxDataSize != null && maxDataSize > 0)
        ? (long)(maxDataSize * 1.1)
        : 0;
    var FileToProcess = new byte[maxDataSize];
    
    Run Code Online (Sandbox Code Playgroud)
  2. 然后我进行另一个数据库调用,从数据库中提取所有文档(没有数据)并将它们放入IEnumerable中.

    UnprocessedDocuments =
        claimDocumentData.Select(StatusCodes.CurrentStatus.WaitingToBeProcessed);
    foreach (var currentDocument in UnprocessDocuments)
    {
         // all of the following code goes here
    }
    
    Run Code Online (Sandbox Code Playgroud)
  3. 然后我从外部源填充我的byte []数组:

    FileToProcess = new BiztalkBinariesData()
        .Get(currentDocument.SubmissionSetId, currentDocument.FullFileName);
    
    Run Code Online (Sandbox Code Playgroud)
  4. 这是个问题.将currentDocument(IClaimDocument)传递给其他要处理的方法会更加清晰.因此,如果我将currentDocument的数据部分设置为预格式化的数组,那么这将使用现有的引用吗?或者这会在大对象堆中创建一个新数组吗?

    currentDocument.Data = FileToProcess;
    
    Run Code Online (Sandbox Code Playgroud)
  5. 在循环结束时,我会清除FileToProcess

    Array.Clear(FileToProcess, 0, FileToProcess.length);
    
    Run Code Online (Sandbox Code Playgroud)

那清楚了吗?如果没有,我会尽力清理它.

Bro*_*ass 6

步骤1:

var FileToProcess = new byte[maxDataSize];
Run Code Online (Sandbox Code Playgroud)

第3步:

FileToProcess = new BiztalkBinariesData()
    .Get(currentDocument.SubmissionSetId, currentDocument.FullFileName);
Run Code Online (Sandbox Code Playgroud)

您的步骤1是完全没必要的,因为您在步骤3中重新分配了阵列 - 您正在创建一个阵列,您没有填充现有阵列 - 所以基本上步骤1只是为GC创建更多工作,如果您这样做它以快速的顺序(如果它没有被编译器优化掉,这是完全可能的)可能会解释你所看到的一些内存压力.

  • 正准备发布这个.另外,行"Array.Clear(FileToProcess,0,FileToProcess.length);" 没有清理任何东西.它不会释放任何内存,只是将值设置为0(但仍然分配).它只做(很多)无用的工作.删除此行. (2认同)
  • @Cyfer13是的,它每次都在创建一个新的字节数组,这就是问题的来源.如果你重新使用在开始时创建的相同数组,它将不会占用超过该数量的内存.数组本身在数据库的execute方法中分配. (2认同)

InB*_*een 5

数组是引用类型,因此您将传递引用的副本,而不是数组本身的副本。这只适用于值类型

这个简单的代码片段说明了数组作为引用类型的行为方式:

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;
}
Run Code Online (Sandbox Code Playgroud)


Ry-*_*Ry- 2

它将使用现有的参考,不用担心。不会复制数组的内容。