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 回答