2

すべて、Append固定テキストファイルの単一行を生成しているときに実行している次のものがあります

formattedLine.Append(this.reversePadding ?
                     strData.PadLeft(this.maximumLength) :
                     strData.PadRight(this.maximumLength)); 

この特定の例外は、PadLeft()where [ SQL Server から収集されthis.maximumLength = 1,073,741,823たフィールドの長さ] で発生します。なぜこれが起こっているのですか?最大許容長は?NVARCHAR(MAX)formattedLine = "101102AA-1"2,147,483,647

https://stackoverflow.com/a/1769472/626442がここでの答えになるかどうか疑問に思っていますが、Dispose()使い捨てオブジェクトの適切な呼び出しでメモリを管理し、using可能な場合はブロックしています。

ノート。この固定テキストのエクスポートは、バックグラウンド スレッドで実行されています。

御時間ありがとうございます。

4

3 に答える 3

3

この特定の例外は、this.maximumLength = 1,073,741,823 の PadLeft() で発生します。

右。つまり、10 億文字を超える文字列を作成しようとしています。

それはうまくいきません。それがあなたが本当にやりたいことなのか、私にはとても疑わしいのです。

char.NET の各文字列は 2 バイトであり、.NET の文字列null で終了することに注意してください。また、データ以外のフィールド (長さなど) がいくつかあります。つまり、少なくとも 2147483652 バイト + オブジェクトのオーバーヘッドが必要になり、オブジェクトあたり 2GB の制限を超えてしまいます。

64 ビット バージョンの Windows で実行している場合、.NET 4.5 には、<gcAllowVeryLargeObjects>2 GB を超える配列を許可する特別な app.config 設定があります。ただし、それによって特定のユースケースが変わるとは思いません。

アプリケーション構成ファイルでこの要素を使用すると、サイズが 2 GB を超える配列が有効になりますが、オブジェクト サイズまたは配列サイズに関するその他の制限は変更されません。

  • 配列内の要素の最大数は UInt32MaxValue です。

  • 任意の 1 次元の最大インデックスは、バイト配列およびシングルバイト構造体の配列の場合は 2,147,483,591 (0x7FFFFFC7)、その他の型の場合は 2,146,435,071 (0X7FEFFFFF) です。

  • 文字列およびその他の非配列オブジェクトの最大サイズは変更されていません。

とにかく、作成した後、そのような文字列で何をしたいですか?

于 2012-11-27T18:57:47.040 に答える
2

この操作にメモリを割り当てるために、OS は操作を実行するのに十分な大きさの連続したメモリを見つける必要があります。

特に 32 ビットの .NET 実装を使用している場合は、メモリの断片化によってそれが不可能になる可能性があります。

于 2012-11-27T18:57:44.943 に答える
1

あなたが達成しようとしていることへのより良いアプローチがあるかもしれないと思います。おそらく、これStringBuilderはファイルに書き込まれる予定であり(あなたの説明からはそう聞こえます)、明らかに、大規模な(巨大な)データベースレコードを処理している可能性もあります。

このような巨大なメモリ ブロックを割り当てる必要がないストリーミング アプローチを検討することもできます。これを達成するには、次のことを調査する必要があります。

このクラスは、単一の大きなレコードのチャンクを読み取ることができるメソッドをSqlDataReader公開します。GetChars()次に、 を使用する代わりにStringBuilder、おそらくStreamWriter(または他のTextWriter派生クラス) を使用して、各チャンクを出力に書き込みます。これには、一度にアプリケーションのメモリ空間で 1 つのレコードのバッファがいっぱいになるだけで済みます。幸運を!

于 2012-11-27T19:14:23.143 に答える