PipelineBuffer不释放内存

时间:2013-04-24 16:47:07

标签: memory-leaks ssis custom-pipeline-component

我正在关注Rainer Stropek上的这篇优秀文章:1。创建自定义SSIS数据流项目& 2.从Azure表存储中提取数据。 http://www.software-architects.com/devblog/2010/11/12/Custom-SSIS-Data-Source-For-Loading-Azure-Tables-Into-SQL-Server

我会粘贴那些试图回答我问题的人感兴趣的代码:

GenericTableContext context = new GenericTableContext(cloudStorageAccount.TableEndpoint.AbsoluteUri, cloudStorageAccount.Credentials);

public override void PrimeOutput(int outputs, int[] outputIDs, PipelineBuffer[] buffers) {
  IDTSOutput100 output = ComponentMetaData.OutputCollection[0];
  PipelineBuffer buffer = buffers[0];
  foreach(var item in this.context.CreateQuery<GenericEntity>("SomeTable") {
    buffer.AddRow();
    for (int x = 0; x < columnInformation.Count; x++) {
      var ci = (ColumnInfo) columnInformation[x];
      var value = item[ci.ColumnName].Value;
      if (value != null) {
        buffer[ci.BufferColumnIndex] = value;
      } else {
        buffer.SetNull(ci.BufferColumnIndex);
      }
    }
  }

现在问题:

我的数据集非常大;让我们说一百万条记录。我有一个最简单形式的SSIS包,即我的自定义数据源将数据写入平面文件目的地。它没有变换。

当我运行我的包时,我可以看到记录被批量写入大约10,000条记录(DefaultBufferMaxRows)。

我的问题是,虽然写了这些记录,但它似乎仍然存在于内存中。这最终导致我的包裹减速并停止。我服务器中的所有内存都用完了。

现在我不是SSIS专家,但我假设我写入PipelineBuffer的记录在消费后没有被释放。 “缓冲区”这个词对我来说意味着它可以被“冲洗”。但我找不到任何API来执行此操作。

所以我想我的问题是,如何释放分配给已经写入平面文件的记录的内存,以便我有足够的内存用于剩余的记录?

谢谢你, Nandun

1 个答案:

答案 0 :(得分:0)

每个缓冲区都会刷新,更准确地说,一旦它完成了通过管道的旅程就会重复使用。因此,SSIS在这种情况下为您管理内存,但您必须确保已分配适当的行和内存大小(您可以在日志记录中打开缓冲区调整事件以查看是否发生在您的程序包中)。通常人们调整内存并且未能意识到它是数据流中的每个组件,并且随后软件包花费大量时间来尝试过度分配大量内存。

如果您的组件是目的地,您也可能无法释放使用连接管理器或在脚本组件中清理资源管理代码所需的连接。