I'm a little confused about how ValueType
objects are managed memory-wise in .NET. I get that value types are put on the stack for each instance/declaration. I'm not quite sure about what constitutes a new instance/declaration. I think my main question is:
If I pass a ValueType
parameter to a method, but do not assign it a value, then is a new instance created on the stack?
开发者_开发技巧I'm not sure if I am phrasing this correctly, so I wrote a simple sample program to make it easier to understand my confusion.
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;
}
}
So, here are my questions with respect to the program.
How many integer instances are created on the stack in this program?
Where in the code, exactly, is each value type instance created on the stack?
Although there is a good chance I am wrong, this is what I think happens, and what I'm not sure about.
Line 1: I know that a new instance created on the stack for variable
MichaelJordan
Line 2: I know that a new instance created on the stack for variable
HoursInADay
Line 3: Is a copy of the value instance from the variable
MichaelJordan
created in order to be a method parameter? Is an instance created of the value23
for the comparison?Line 4: The value for the
LastNumberThatWasnt23
field is not initialized, so it returns the default value. Is a new instance with the default value created for this field?Line 5: Same questions as Line 3, but also, I know that a new instance is created on the stack for the field
LastNumberThatWasnt23
because I am setting it.Line 6: Now, the field has a value. But, in referencing that value and passing it into the
Console.WriteLine
method, am I creating a new value instance on the stack?
I have one more part to this question, which is How would I find out stuff like this? Can I do it programmatically? Are there any tools that can be used to reveal this kind of information?
I know this is a long question, so I thank you for taking the time to read it.
This depends on the jitter your machine uses to run this program. But since you use only two local variables, it is very likely the correct answer is zero. The jit optimizer stores the variable values in CPU registers. That's one of the standard optimizations.
You'll find more about the kind of optimizations that the jitter performs in this answer.
It's complicated. The Jitter is allowed pretty much free reign. It can put a local variable into a register, or on the stack, or both, or first in one than the other. There is no simple correspondence between local variables and stack allocations.
You can find that stuff out by disassembling the asm code(not the IL). And even then it depends on compilerflags, the presence of a debugger, the exact content of your method, the .net version,...
But why does it matter at all? The stack memory consumed by local variables is negligible unless you recurse very deeply.
memory allocation of value types and reference types in .net framework should answer most if not all of your questions.
精彩评论