Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/272.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# MichaelJordan在.NET中的堆栈上创建了多少ValueType实例?_C#_.net_Performance_Struct_Stack - Fatal编程技术网

C# MichaelJordan在.NET中的堆栈上创建了多少ValueType实例?

C# MichaelJordan在.NET中的堆栈上创建了多少ValueType实例?,c#,.net,performance,struct,stack,C#,.net,Performance,Struct,Stack,在.NET中,ValueType对象是如何在内存方面进行管理的,对此我有点困惑。我发现每个实例/声明的值类型都放在堆栈上。我不太确定什么构成了一个新的实例/声明。我想我的主要问题是: 如果我将ValueType参数传递给一个方法,但没有给它赋值,那么是否在堆栈上创建了一个新实例? 我不确定我的措辞是否正确,因此我编写了一个简单的示例程序,以便更容易理解我的困惑 void Main() { //-------------------------| Line 1: int Mich

在.NET中,
ValueType
对象是如何在内存方面进行管理的,对此我有点困惑。我发现每个实例/声明的值类型都放在堆栈上。我不太确定什么构成了一个新的实例/声明。我想我的主要问题是:

如果我将
ValueType
参数传递给一个方法,但没有给它赋值,那么是否在堆栈上创建了一个新实例? 我不确定我的措辞是否正确,因此我编写了一个简单的示例程序,以便更容易理解我的困惑

void Main()
{
    //-------------------------|  Line 1:
    int MichaelJordan = 23;      
    //-------------------------|  Line 2:   
    int HoursInADay = 24;           
    //-------------------------|  Line 3:
    Console.WriteLine("Michael Jordan is "+(NumberHelper.Is23(MichaelJordan) ? string.Empty : "not ")+"23");
    //-------------------------|  Line 4:
    Console.WriteLine("The last number that wasn't 23 was "+NumberHelper.LastNumberThatWasnt23);
    //-------------------------|  Line 5:
    Console.WriteLine("Hours in a Day is "+(NumberHelper.Is23(HoursInADay) ? string.Empty : "not ")+"23");
    //-------------------------|  Line 6:  
    Console.WriteLine("The last number that wasn't 23 was "+NumberHelper.LastNumberThatWasnt23);
}

public static class NumberHelper {  
    public static int LastNumberThatWasnt23;
    public static bool Is23(int candidate){
        if(candidate != 23){
            LastNumberThatWasnt23 = candidate;
            return false;
        }
        return true;
    }
}
因此,以下是我关于该计划的问题。
  • 此程序在堆栈上创建了多少个整数实例?

  • 堆栈上创建的每个值类型实例在代码中的什么位置?

  • 虽然我很有可能错了,但这是我认为会发生的事情,我也不确定。
    • 第1行:我知道在堆栈上为变量
      MichaelJordan创建了一个新实例

    • 第2行:我知道在堆栈上为变量
      hoursinday创建了一个新实例

    • 第3行:是在中创建的变量
      MichaelJordan
      的值实例副本 作为方法参数的顺序?是否为比较创建了值
      23
      的实例

    • 第4行:未初始化
      LastNumberThatWasnt23
      字段的值,因此它返回默认值。是否为此字段创建了具有默认值的新实例

    • 第5行:与第3行的问题相同,但是,我知道在堆栈上为字段
      LastNumberThatWasnt23
      创建了一个新实例,因为我正在设置它

    • 第6行:现在,该字段有一个值。但是,在引用该值并将其传递到
      Console.WriteLine
      方法时,我是否在堆栈上创建了一个新的值实例

    这个问题还有一个部分,那就是我怎样才能找到像这样的东西?我可以通过编程来完成吗?有什么工具可以用来揭示这类信息吗


    我知道这是一个很长的问题,所以我感谢您花时间阅读。

    如果不是所有问题,也应该回答大部分问题。

    这很复杂。抖动几乎可以自由支配。它可以将一个局部变量放入寄存器中,或放入堆栈中,或两者都放入,或先放入一个而不是另一个。局部变量和堆栈分配之间没有简单的对应关系

    您可以通过反汇编asm代码(而不是IL)找到这些内容。即使如此,它也取决于编译器标签、调试器的存在、方法的确切内容、.net版本


    但这有什么关系呢?局部变量消耗的堆栈内存可以忽略不计,除非递归非常深入。

    这取决于计算机运行此程序时使用的抖动。但是因为你只使用了两个局部变量,很可能正确的答案是零。jit优化器将变量值存储在CPU寄存器中。这是标准的优化之一


    你会发现更多关于抖动执行的优化类型。

    Zero-他退休了。:)本周我看到的与迈克尔·乔丹有关的最佳编程问题是:JIT,即时编译器。这是.NET将IL代码转换为实际处理器代码的部分。