2

参照型の浅いコピーを正しく理解していること、およびここで巨大なメモリリークを構築していないことを確認するためだけに:

// Adds text to the beginning of the log RTB
// Also keeps the log RTB trimmed to 100 lines
var lines = new string[rtbLog.Lines.Length + 1];
lines[0] = "text";
Array.Copy(rtbLog.Lines, 0, lines, 1, rtbLog.Lines.Length);

if (lines.Length > 100)
{
    Array.Resize(ref lines, 100);
}

rtbLog.Lines = lines;

これは、最初に rtbLog.Lines の文字列への参照を行にコピーします。次に、行から最初の 100 個の参照を新しい文字列配列にコピーします。

つまり、rtbLog.Lines が最初に参照していた配列、(サイズ変更前) 行によって最初に参照された配列、最後に (サイズ変更後) 行に含まれていないすべての文字列がすべてガベージ コレクションされます。(それが理にかなっていることを願っています)

正しい?

4

2 に答える 2

1

Array.Resize メソッドは少し間違った名前です。CopyToNewArrayWithSize という名前にする必要があります。内部では、この API は新しい配列を作成し、指定されたデータをその配列にコピーします。次に、新しい配列が参照によって返されます。

ガベージコレクションについて。Lines プロパティを新しい配列にリセットすることで、配列への元の参照を正常に削除できました。配列への他の参照がない限り、将来のある時点でガベージ コレクションが行われます。

于 2009-04-26T23:00:43.923 に答える
0

はい、使用されなくなった元の配列と文字列は、問題なくガベージ コレクションされます。

配列を作成する前に必要なサイズを計算する場合は、呼び出す必要はありませんResize(配列の別のコピーが作成されるため)。

// Adds text to the beginning of the log RTB
// Also keeps the log RTB trimmed to 100 lines
int size = Math.Min(rtbLog.Lines.Length + 1, 100);
string[] lines = new string[size];
lines[0] = "text";
Array.Copy(rtbLog.Lines, 0, lines, 1, size - 1);
rtbLog.Lines = lines;
于 2009-04-26T23:43:26.100 に答える