Возвращаемое значение Объем памяти - PullRequest
3 голосов
/ 21 апреля 2011

Если у меня есть метод, подобный:

public SomeObject GetObject(int ID){

    SomeObject obj1 = new SomeObject();

    obj1.ID = ID;

    return obj1;
}

Тогда, если я использовал метод, подобный этому:

SomeObject obj2 = GetObject(4);

Будет ли obj2 просто ссылкой в ​​памяти на obj1 или он будет скопирован в память и существует два полных объекта?

А когда GC удалит из памяти obj1, если последнее верно?

Ответы [ 6 ]

5 голосов
/ 21 апреля 2011

Это зависит от типа.Существуют типы значений и ссылочные типы.

Типы значений сохраняют само значение в памяти, и каждый раз, когда вы его передаете, вы просто копируете значение (то есть тип значения), если только выиспользуйте что-то вроде public void Test(ref int x).Факт наличия ref означает передачу целого числа по ссылке.

Когда у вас есть переменная ссылочного типа (объект), вы в основном просто держите указатель.Таким образом, он выдал бы ту же ссылку на объект.

Вы можете подтвердить это, расширив свой код, выполнив что-то вроде этого:

obj2.ID = 3;
Console.WriteLine(obj1.ID); // => 3

obj1 (или сам объект, так как obj1 являетсяпросто ссылка) будет GC'd, когда больше нет ссылок на объект.

3 голосов
/ 21 апреля 2011

Если SomeObject извлекается из ValueType , то экземпляр, который находится в области действия GetObject, будет уничтожен, как только он вернется, и будет создан новый экземпляр и назначен obj2.Если SomeObject не является ValueType, то есть ссылочным типом, тогда будет возвращена только его ссылка, так что вы получите 1 экземпляр.Невозможно предсказать, когда GC уничтожит объект, однако GC уничтожает только ссылочные типы, ValueTypes уничтожаются автоматически, когда выполнение кода выходит за пределы его области действия.

2 голосов
/ 21 апреля 2011

Если предположить, что SomeObject является классом, метод вернет ссылку на экземпляр объекта, который он создает.

Экземпляр объекта не будет скопирован, существует только один экземпляр. В .NET копирование объектов не происходит, если вы специально не попросите сделать копию, например, вызвав метод Clone.

Говоря о ссылочных типах, важно помнить разницу между экземплярами объектов, ссылками на экземпляры и переменными, которые содержат ссылки. Переменная obj1 содержит ссылку на экземпляр, и переменная выделяется в кадре стека для метода, поэтому она исчезает при выходе из метода. Ссылка возвращается из метода, но в то время переменная больше не существует.

2 голосов
/ 21 апреля 2011

Будет obj2 просто ссылка в памяти на obj1
Да (при условии, что это не тип значения)

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

public class SomeObject
{
    public string Name { get; set; }
    public int ID { get; set; }
    public SomeObject() { ID = 1; Name = "test"; }
}

static void Main(string[] args)
{
    SomeObject obj1 = new SomeObject();
    GetObject(obj1, 2);

    Console.WriteLine(obj1.ID); // prints 1
    Console.Read();
}

public static void GetObject(SomeObject obj1, int id)
{
    var obj = new SomeObject();
    obj.ID = id;
    obj.Name = "";

    obj1 = obj;
}
1 голос
/ 21 апреля 2011

Это будет ссылка в памяти на obj1, при условии, что obj1 является class, а не struct.

0 голосов
/ 21 апреля 2011

Если какой-либо объект является ссылочным типом, вы правы в том, что вы получите справочную копию, если SomeObject является типом значения, вы получите копию.Сборщик мусора очистит SomeObject через некоторое время, когда решит, что хочет освободить память.Однако вы можете форсировать руку GC, позвонив в GC.collect

...