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

本文关键字:引用 有效地 byte | 更新日期: 2023-09-27 18:22:12

所以这与处理大型对象堆和尽量减少实例化字节的次数有关[]。基本上,我有OutOfMemoryException,我觉得这是因为我们实例化了太多字节数组。当我们处理几个文件时,该程序运行良好,但它需要扩展,而目前无法扩展。

简而言之,我有一个从数据库中提取文档的循环。目前,它一次提取一个文档,然后处理该文档。文档的范围从小于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];
    
  2. 然后,我进行另一个数据库调用,从数据库中提取所有文档(没有数据),并将这些文档放入IEnumerable中。

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

    FileToProcess = new BiztalkBinariesData()
        .Get(currentDocument.SubmissionSetId, currentDocument.FullFileName);
    
  4. 问题来了。将currentDocument(IClaimDocument)传递给其他方法进行处理会干净得多。因此,如果我将currentDocument的数据部分设置为预先格式化的数组,这会使用现有的引用吗?或者这会在大型对象堆中创建一个新数组?

    currentDocument.Data = FileToProcess;
    
  5. 在循环结束时,我会清除FileToProcess

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

清楚吗?如果没有,我会尽力把它清理干净。

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

步骤1:

var FileToProcess = new byte[maxDataSize];

步骤3:

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

步骤1完全没有必要,因为您在步骤3中重新分配了数组-您正在创建一个新的数组,而不是填充现有的数组-因此,从本质上讲,步骤1只是为GC创建更多的工作,如果您按快速顺序执行(如果编译器没有对其进行优化,这是完全可能的),这可能会解释您所看到的一些内存压力。

数组是引用类型,因此您将传递引用的副本,而不是数组本身的副本。只有在值类型的情况下才会出现这种情况。

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

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;
}

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

您的问题可能在于"BiztalkBinariesData"类的实现和使用。

我不确定它是如何实现的,但我确实看到你每次都会声明一个新的实例

new BiztalkBinariesData()

需要思考的事情。。

我有OutOfMemoryException,我觉得这是因为我们实例化了太多字节阵列的

不,这是因为您分配了LARGE数组。将它们限制为48kb或64kb,并将它们与自定义容器"组合"在一起。64kb意味着您可以使用索引中较高的2个字节来确定要使用的数组。容器包含一组数组。处理非常大的对象会导致碎片化,并且以后无法分配一个大数组。