Memory Allocation Question?
public static void Main()
{
Test t1 = new Test();
}
when will t1 (reference 开发者_运维知识库variable) will get memory, at compile time or run time.
I think it should be run time. But when I put a breakpoint at Main Method and Put a Watch for t1, it was null. So it means t1 was in memory.Please correct me If I am wrong.
Edit: I heard Static Member Variables are assigned at compile time.
Memory is only allocated at runtime (at compile time your app isn't running).
At runtime, your t1
variable will only have a value (i.e. not null
) after the assignment has occurred, so it depends where you put your breakpoint. If you put your breakpoint on the closing brace of your Main
method and check the watch window when it's hit, you'll see what I mean.
I.e. If you put your breakpoint on the assignment line Test1 t1 = new Test1();
then that line hasn't been executed yet, so the assignment hasn't happened.
The reference t1 is assigned on the stack frame of the Main method - the value you assign to it (i.e. the 'new Test()' part) is allocated on the heap at runtime - this is why the t1 variable exists before that line has executed and is null.
Test t1;
This part allocates enough space only for a reference (probably 4 bytes in many cases, but I think it really depends on the .NET framework implementation), and is determined at compile time and allocated (I think) when Main is called.
t1 = new Test();
This line, when it runs, will allocate enough space to store the data for a Test object and then assign the existing reference variable t1 to refer to that newly allocated memory. So now you have the space for t1 plus the space for new Test() both allocated.
Edit: To respond to your edit, static member variables are different, and your local variable behaves differently than they do. However, I don't believe that static member variables are allocated at compile time. I think they are allocated when the type containing them is loaded (which, seems to be when any function is called that refers to the type).
class Test2
{
public static Test f1 = new Test();
}
This code would create a new instance of Test as soon as a function that contains any a reference to type Test2 is called.
At the start of 'Main', the heap memory for the instance hasn't been allocated yet (and won't be until new Test()
). It will remain allocated until it's garbage-collected.
The local variable, Test t1
(stack-based), that will reference the heap memory does exist (and exists for the whole time that 'Main' is executing).
Both of these are run-time assignments, but differ in terms of where the memory resides and for how long.
Static fields are allocated when the type loads (and are initialized some time between then and the type's first use).
By 'compile-time', I'm not sure if you're referring to JIT compile - but whichever way, the memory is allocated separately from compilation.
No it means t1 has not been assigned yet. Once you call the new Test()
t1 will be allocated memory to store the size of a Test
object and is assigned a memory address.
Yes memory is only allocated at run-time.
You should be able to figure this one out yourself. Just think about it:
- When you allocate memory, you "use" memory for something.
- A program that does not run, does not use memory.
- A program that does run, uses memory.
- At run-time, means a program is running.
- Memory is used, allocated, at run-time.
Allocating memory compile-time, just doesn't make any sense...
Having read the above answers, let me try to phrase the answer in a better way.
Lets put the code this way:
Main()
{
Test t1;
t1 = new Test();
}
Now, lets start:
- Put your debug points at {, Test t1, t1 = new Test() and }
- Run the program
Let the statement { execute- there is nothing with the name t1 - Why??
The programming is running. The compilation was done ages ago. Still - t1 is never allocated memory. Why?
Go to the next debug point and let the statement
Test t1
execute.Now check - you will find t1 exists within the local variable/memory list.
Why? The statement was processed and it was RUN/RAN/Executed. So, it was allocated memory.
Now - what memory was allocated? It was just a memory required for Reference/Pointer/Object. It should obviously have the value null. So - how much memory do you think it takes?
Now let the next statement execute.
This time, the value of null is replaced by something else - and that does occupy a variable amount of memory, depending of what it does/has.
Process the next statement:
What happens now is that your object no longer exists/or is no longer referenced.
Is there memory still allocated for the object still existing/ the memory allocated for
new Test()
the memory allocated for Test t1? – Yes!This memory continues to stay, but luckily - the Garbage Collector exists and cleans out the garbage.
From efficiency point of view, it is preferred to set
Test t1=null
, so that, in case the main function has lot of other statements to work with, then it can de-allocate the memory assigned for the new Test() by signalling the garbage collector that this chunk of data is no longer required.At the end of
Main
(or the scope of the variable), the pointer is checked by the garbage collector for referencing some value - if it doesn't (since its null), it just goes ahead and de-allocates the reference/object memory as well.
@Static stuff : I am trying to find out about static classes/variables and methods myself.
@People: Correct me if I am wrong at some place.
run the application in the debugging mode, F5 is mostly the keyboard shortcut in visual studio. Put a breakpoint at this statement. Use the F10 to step to next statement. Moment the debugger steps next statement you would see the object being created.
精彩评论