2013-08-09 2 views
2

Привет, я искал ответ на этот вопрос довольно долго. Я хочу знать вещи под капотом относительно того, когда мой код будет заменен памятью.Объявление переменной уже занимает память

Ex. int myVar;

  1. Этот код уже занимает память? по памяти я имею в виду стек? и изначально в .NET. Я заметил, что эта строка будет иметь значение по умолчанию ZERO (0).
  2. Но какая переменная действительно хранится? значение ZERO или адрес, где хранится значение ZERO (0)?

также от того, что я понимаю, о ссылочного типа является то, что, когда я пишу эту строку кода

MyClass myObj; // Объявляем только

myObj = новый MyClass() // создать экземпляр

Я хочу знать, что происходит под капотом. Правильны ли мои предположения? То, что myObj будет находиться в стеке, и myObj способен хранить адрес. и при моем создании объекта объект создается в куче, и адрес этого объекта передается переменной myObj.

Дело в том, что я хочу знать, эффективнее (с точки зрения памяти и производительности) между двумя ниже.

Код 1: int myVar; myVar = FunctionThatReturnsAnInteger(); Console.WriteLine (myVar);

Код

Console.WriteLine (FunctionThatReturnsAnInteger());

Я хочу хорошее объяснение этому, и аналогия весьма удобна.

Заранее спасибо. :)

+0

я попытался создавая указатель, 2 разные неинициализированные целочисленные переменные. назначая адрес двух целых чисел по одному и печатая их соответственно. Они показали два разных адреса. Я полагаю, что к моменту объявления они уже занимают память? –

+0

Для получения дополнительной информации вы должны проверить следующую ссылку: [msdn] (http://msdn.microsoft.com/en-us/library/vstudio/ms173104.aspx) espcially ** Типы, которые происходят из ValueType, имеют особое поведение в CLR. Переменные типа значения непосредственно содержат их значения, а это означает, что память выделена встроенным в любом контексте, в котором объявлена ​​переменная **, и для ссылочных значений ** Когда объект создается, память выделяется в управляемой куче, а переменная имеет значение только ссылка на местоположение объекта ** – Marco

+0

@ Марко благодарю вас за ответ и хорошую ссылку. Можете ли вы ответить на мой последний вопрос, в котором больше памяти. Объявление переменной и улавливание возвращаемого значения вызываемой и отображаемой функции ИЛИ прямого вызова функции и использования параметра return в качестве параметра для Console.WriteLine() –

ответ

2

Эффективность работы - более эффективная, но только с помощью нескольких инструкций, хранения и загрузки переменной из стека выполнения. Имейте в виду, что Jitter может оптимизировать ваш код во время выполнения, удаляя любые ненужные инструкции.

Эффективность памяти - более эффективна, так как в стеке выполнения нет локальных переменных.

Четкость кода - определение переменной, приближенной к тому, где она используется, делает код более пригодным для использования. По-моему, использование одного метода, возвращающегося в другое, еще более чистое, но имеет недостаток, что сложнее проверить возвращаемое значение (в VS 2013 это будет возможно).

IL с переменной TEMP:

// Code size  13 (0xd) 
    .maxstack 1 
    .locals init ([0] int32 myVar) 
    IL_0000: call  int32 StackOverflowScratchPad.Program::FunctionThatReturnsAnInteger() 
    IL_0005: stloc.0 
    IL_0006: ldloc.0 
    IL_0007: call  void [mscorlib]System.Console::WriteLine(int32) 
    IL_000c: ret 

и без:

// Code size  11 (0xb) 
    .maxstack 8 
    IL_0000: call  int32 StackOverflowScratchPad.Program::FunctionThatReturnsAnInteger() 
    IL_0005: call  void [mscorlib]System.Console::WriteLine(int32) 
    IL_000a: ret 

Bonus - IL при назначении значения темпа вара при объявлении:

// Code size  15 (0xf) 
    .maxstack 1 
    .locals init ([0] int32 myVar) 
    IL_0000: ldc.i4.5 
    IL_0001: stloc.0 
    IL_0002: call  int32 StackOverflowScratchPad.Program::FunctionThatReturnsAnInteger() 
    IL_0007: stloc.0 
    IL_0008: ldloc.0 
    IL_0009: call  void [mscorlib]System.Console::WriteLine(int32) 
    IL_000e: ret 
+0

Большое спасибо за ваш замечательный ответ! +1 для вас :) –

Смежные вопросы