Этот образец генерирует мусор? - PullRequest
2 голосов
/ 09 января 2012
public class Foo
{
    public void Draw() // Called 60 times per second
    {
        spriteBatch.Draw(new Vector2(x, y), null, Color.White);
    }

    private float x, y;
}

В частности, мне интересно, генерирует ли вызов new Vector2(x, y) мусор или нет.

Насколько я понимаю, поскольку Vector2 является типом value , ине сохраняется как элемент типа reference , он будет создан в стеке.Поэтому его память должна автоматически восстанавливаться, как только возвращается метод Draw, не создавая мусора.

Это правильно?


РЕДАКТИРОВАТЬ

Если я могу запросить дополнительные разъяснения по поводу первоначальной должности Эрика Липперта.

Вопрос 1)

Это зависит от того, является ли первый формальный параметр вызванногоФункция принимает ссылочный тип или тип значения.Если он принимает тип значения, то нет, здесь не генерируется мусор.Если он принимает ссылочный тип, то значение будет помещено в коробку.

Тогда, если подпись окажется такой:

public void Draw()
{
    Vector2 vector = new Vector2(x, y);
    spriteBatch.Draw(ref vector, null, Color.White);
}

Будет ли генерироваться мусор из упакованного вектора?

Вопрос 2)

То, что его нет в куче, логически не влечет за собой его генерацию в стеке.Это может быть в регистре.

Но я предполагаю, что хранение в регистре ведет себя как хранение в стеке с точки зрения сборщика мусора.Это правильно?

Ответы [ 2 ]

5 голосов
/ 09 января 2012

Мне интересно, генерирует ли вызов new Vector2(x, y) мусор или нет.

Это зависит от того, принимает ли первый формальный параметр вызванной функции ссылочный тип или тип значения. Если он принимает тип значения, то нет, здесь не генерируется мусор. Если он принимает ссылочный тип, значение будет помещено в коробку.

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

То, что он не находится в куче, логически не означает, что он генерируется в стеке. Это может быть в реестре.

если подпись требует прохождения структуры "по ref" (с использованием модификаторов "ref" или "out"), будет ли какой-нибудь бокс?

Нет. Вы смешиваете два вида ссылок. «Ссылка», которая является псевдонимом для переменной , не является объектом:

void D(int q) {}
void D(ref int q) {}
void D(object q) {}

Первый метод D берет копию целого числа. Второй D создает псевдоним переменной, содержащей неупакованное целое число. Третье D занимает целое в штучной упаковке.

Я полагаю, что хранение в регистре ведет себя как хранение в стеке с точки зрения сборщика мусора.

Это неверное предположение. Предположим, что значение, которое либо зарегистрировано, либо помещено в стек , содержит ссылку на объект сбора мусора . Джиттер имеет право обрабатывать зарегистрированные ссылки иначе, чем ссылки на стек. Предположим, например, что алгоритм распределения регистров дрожания решает повторно использовать этот регистр для чего-то еще, после того как дрожание узнает, что ссылка больше не будет разыменовываться. Дрожание совершенно свободно, а затем сказать сборщику мусора, что ссылка исчезла. Таким образом, возможно, что 'this' освобождается потоком GC, даже когда метод объекта выполняет .

Джиттер, конечно, также свободен для стека, но это было бы гораздо более агрессивной оптимизацией.

3 голосов
/ 09 января 2012

Правильно, Vector2 будет жить в соответствующих кадрах стека (как и Color) - обратите внимание: поскольку оно не передается ref, значение будет скопировано в кадр Draw стека. Vector2 действительно маленький (64 бита / 8 байт), и это, скорее всего, не проблема, но как только каждый кадр стека будет сделан с Vector2, память будет освобождена.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...