3

Do methods (and their variables) that belong to an object instance go on the stack or the heap?

Ex

Main()
{
Myclass Myobj = new Myclass();
Myobj.Doit();
}

class Myclass
{
 Void Doit()
 {
 Int myint = 5;
 }
}

I use c# primarily, but I assume the answer is language agnostic.

  • 2
    The answer is not language agnostic, and stirctly speaking a generic answer is incompatable with the correct interpretation of the C# language definition. – mattnz Oct 23 '14 at 2:57
12

The CLR standard does not require a stack or a heap, so lets get that out of the way first. But C# implemented on paper isn't very useful. I describe here the implementations we can run code with "in practice", like the Microsoft C# or Mono C#. Regardless, the method and local variables have a conceptual relationship with classes and object instances that you have to understand, because it isn't specific to C#, it is the same for computer languages in general.

Instance methods are stored in the same way that static methods are.

Methods are part of the code (in CLR, bytecode), they are compiled instructions, low level CLR opcodes that make up the assembly. So in the C# model they aren't part of a heap, the heap is for data. (See caveat footnote at bottom). In languages that aren't object oriented, there are plain functions. In those languages, the functions are just code that receives arguments. In CLR a plain function is a static method (or class method). The only difference in a function and a method is that syntactic sugar makes the function appear to be owned, but its object is really just the first "implicit" argument (this), and in most languages it comes before the method call, ie. obj.Foo(). The first argument to the function must still be loaded by an instruction; in CLR MSIL, this is loaded by ldarg.0 except in the case of a static method. So obj.Foo(arg) is equivalent to Foo(obj,arg).

When you compile a class, the compiler emits a set of instructions that represent the method and packs it into a code segment.

The relationship of the method to the object is actually similar to the relationship of class to object. The method is part of the class (ie part of the type, not part of the object. The method is akin to static data, but the "method data" happens to be code. Like static fields, the methods exist prior to and without any existence of an object instance and are just part of the object's type. I might have 1,000,000 instances of a string, but there is a single copy of string::Concat(string) somewhere.

As far as a method's local variables, they do not exist until the method is called. At the beginning of a CLR method, the call frame assures space for all local variables in that method. They are known ahead of time, but are simply formal notation until the method runs, then they become real data addresses. An instruction tells the CLR how much space to allocate. Local variable values are conceptually and practically on the stack, yet mapped to registers. The variables are "local" to the scope of the method, and go away when the method returns (though the objects they refer may not). There are instructions for dealing with them in CLR. Lets look at a rough sample of MSIL (IL assembly for CLR) for your DoIt() method.

.method void MyClass::Doit()
{
    .locals init([0]int myint)   // declares the locals for the method
    ldc.i4.5
    stloc 'myint'                // initialize myint to 0
    ret
}

Locals are aggressively mapped to real CPU registers by the JIT compiler so they mostly exist on a stack when CLR is interpreting or verifying bytecode. In practice, locals exist in registers, but spill over to a stack on the low level hardware.

Finally, for any computer language, there are 3 primary groups of syntax.

  1. Type declarations and definitions (formal ideas, compiler enforced, and metadata)
  2. Algorithmic (code, methods, statements, expressions)
  3. Data and variables (data)

Caveat: Runtime systems are commonly implemented in C or C++. A CLR assembly and its methods are loaded into the runtime heap of the host language used to write the CLR. But conceptually that is a different heap than the "heap" you are accessing within the CLR.

  • 1
    Thank you for you answer. I am glad I came back to see it again. It is the most useful answer I have ever received on a question on this site or any of its sister sites (multiple accounts). – WZRh1jq91 May 2 '16 at 11:58
  • Glad you found it useful. – codenheim May 3 '16 at 18:19
3

In general, program code exists in an area outside of what you mean when you say "stack" and "heap." While you mentioned C#, there are no language tags so I will describe how a typical modern desktop OS handles this at a low level.

When your program loads, there are two main areas of memory: code and data. The OS allocates enough memory to load the program, which contains the executable code, static data (e.g. constants), and whatever bootstrap code the compiler includes (something has to call main).

In this sense the code is on a heap, simply because everything is heap allocated from the perspective of the OS. However, from the vantage point of your program, it is outside your program's stack and heap. You cannot allocate memory in either location and put code in it, generally (exception: next paragraph).

Some languages allow eval or exec calls where a variable is executed as code, which could include a function and a call to that function. In that sense the code could exist in the stack or heap, although the details are abstracted away most of the time in languages that allow that (e.g. Perl or PHP). It is difficult to impossible to know for sure where the code resides in this case.

This separation of code away from the data segment (and therefor the heap and stack) is only becoming stronger as newer CPUs have hardware-level support for forbidding execution of code from the data segment. The idea is to help neutralize viruses which depend on that to modify running code and therefor spread and evade detection. If a program is subject to the execute flag protection, code cannot be run from the data (stack and heap) part of memory.

0

In C# memory management is an implementation detail. There is no guarantee whatsoever where your objects will go.

There isn't even the guarantee that a 'stack' even exists in the operating system running it.

Don't base any logic on it.

The article where I have my knowledge from:

http://blogs.msdn.com/b/ericlippert/archive/2009/04/27/the-stack-is-an-implementation-detail.aspx

  • 1
    Why would that be important for you? Whats the case you are trying to solve? This is something teh garbage collector has to worry about and i would highly recommend not messing with him. – MrDosu Oct 22 '14 at 2:05
  • 2
    This is ridiculous. If you dont know that is fine. I will not argue the reasons I am asking a question. In fact, if you knew an answer it would've taken you less effort to simply answer. There are many videos and articles about the stack and heap. Apparently, they matter. None go as far to answer my question. – WZRh1jq91 Oct 22 '14 at 2:17
  • 1
    Your question is answered in the first line of my answer. Read the article. Not all programming languages are the same. If you would have asked about C this would be a very different conversation. – MrDosu Oct 22 '14 at 2:21
  • 4
    @DCL "I will not argue the reasons I am asking a question." Please consider the XY problem – Jan Doggen Oct 22 '14 at 7:26
  • 1
    @DCL: In Java, the situation is similar. The Java Language Specification does not say anything about a stack or a heap. It does not say anything about where and how objects, classes, interfaces, static methods, instance methods, constructors, finalizers, static fields, instance fields, local fields etc. are stored. It does not say anything about any particular representation. – Jörg W Mittag Oct 22 '14 at 7:38

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.