Вопрос о массивном копировании в C # - PullRequest
2 голосов
/ 27 апреля 2009

Просто чтобы убедиться, что я правильно понимаю мелкие копии ссылочных типов и что я не создаю здесь огромную утечку памяти:

// 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, массив, на который изначально ссылаются строки (до изменения размера), и, наконец, любые строки, не содержащиеся в строках (после изменения размера), все они собирают мусор. (Надеюсь, это имеет смысл)

Правильно?

Ответы [ 2 ]

1 голос
/ 27 апреля 2009

Метод Array.Resize немного ошибочен. Он должен действительно называться CopyToNewArrayWithSize. Внутри этого API будет создан новый массив и скопированы указанные данные в этот массив. Новый массив затем возвращается по ссылке.

Что касается сбора мусора. Сбросив свойство Lines в новый массив, вы успешно удалили исходную ссылку на массив. Пока нет никаких других ссылок на массив, он будет собирать мусор в будущем.

0 голосов
/ 27 апреля 2009

Да, исходный массив и строки, которые больше не используются, просто удаляются мусором.

Если вы вычисляете нужный размер до создания массива, вам не нужно вызывать 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;
...