4

If we had code like this:

public class Enemy
{
   public int hp;
}

Then an Enemy object would take 4 bytes in 32-bit machines, and 8 bytes in 64-bit (correct me if I'm wrong).

If we change it to something like this:

public class Enemy
{
   public int hp;
   public void Attack() {}
}

An Enemy object would still take the same amount of memory as it did before, right?

The same for this:

public class Enemy
{
   private int hp;
   public int Hp { get { return hp; } set { hp = value; } }
}

From what I know, a property is function, but treated as a variable, right?

So if we did this:

public class Enemy
{
   public int Hp { set; get; }
}

Does that mean, an Enemy object now takes no memory space at all? That doesn't make any sense.

Or even this, for that matter:

public class Enemy
{
   public void DoSomething() { }
}

Can somebody explain?

johnnyRose
  • 7,310
  • 17
  • 40
  • 61
vexe
  • 5,433
  • 12
  • 52
  • 81
  • At minimum - every instance of a class requires at least one pointer to it, or it'll be garbage collected. There's additional information for bits of framework overhead, which varies. The amount of memory required per-method varies by implementation. Attempting to account for every byte used in languages like this can be very difficult, because you don't have direct control over it. Why do you need to know? Or is it just about auto-properties? – Clockwork-Muse Oct 14 '13 at 07:56
  • I just want to understand how does this thing work. I originally asked to know about properties. But then since they're like functions, I also wanted to know about them. – vexe Oct 14 '13 at 08:01
  • `object would take 4 bytes in 32-bit machines, and 8 bytes in 64-bit (correct me if I'm wrong)` Am not sure about it. Whatever 32 bit or 64bit you run, `int` will be 4 bytes that is why it is named as `Int32`. I think you're confusing `IntPtr` with `int`. Correct me if am wrong – Sriram Sakthivel Oct 14 '13 at 08:02

3 Answers3

6

int in C# is always going to be System.Int32 which will always take up 4 bytes of space, regardless of 32-bit or 64-bit application.

However, there's additional overhead in an object. Jon Skeet has a blogpost that details some of this here, Of memory and strings.

As you can see, the base size of an object is 12 bytes when running as 32-bit, even if you have no fields.

You're right, however, in that a property that has code does not necessarily increase the size of the object.

However, if you make it an auto-property, like this:

public int Hp { get; set; }

Then the compiler will automagically create a backing field for you to hold the value of that property, which will again take up space.

johnnyRose
  • 7,310
  • 17
  • 40
  • 61
Lasse V. Karlsen
  • 380,855
  • 102
  • 628
  • 825
2

public int Hp { set; get; } means - AUTOgenerate variable, and its access methods, so this variable will take space, the same as you manually define it.

more details:

your code is compiled into any kind of binary code (either pure machine codes, or byte code) - so, your code is always occupy some memory during storing on HD or during running in RAM, also - for each instance of any class, during runtime additional memory for variables of this class is allocated, so all your classes take memory, classes without variables use almost 0 additional memory for each instance, but there are can be some "technical" data for each instance, like vrtbl, so usually - all classes and all objects takes some memory

CodesInChaos
  • 106,488
  • 23
  • 218
  • 262
Iłya Bursov
  • 23,342
  • 4
  • 33
  • 57
1

public int Hp { set; get; } Is an auto-implemented property, a private field will be generated at compile-time.

like:

public class Enemy
{
   public int Hp { set; get; }
}

Will be implemented as.

public class Enemy
{
   private int _hp;

   public int Hp 
   { 
       get { return _hp; }
       set { _hp = value; }
   }
}

Also adding extra method will use extra memory, but not per-instance. Look: Where are methods stored in memory?

Community
  • 1
  • 1
Jeroen van Langen
  • 21,446
  • 3
  • 42
  • 57
  • Thanks. But what about my 2nd example, where I have a function and a variable, how much memory would that take? (I guess it will take the same amount as in my 3rd example, right?) – vexe Oct 14 '13 at 07:53
  • Oh yes, I've seen your edit, yes I remember reading that. So, it's like, code (functions) take the same space, even if I had numerous objects. That makes sense because it's just code, they all use it, so it's shared between the objects I guess, right? – vexe Oct 14 '13 at 07:55
  • Hmm, from the link you gave me: "class fields are stored in the heap" is that true, even for trivial data types, like int, float, etc? I thought those lived in the stack. But I guess, since the class object itself lives in the heap, that's why all its members are in the heap as well, cause they're inside it, am I correct? – vexe Oct 14 '13 at 08:10
  • 1
    A class is a reference type. _(because when you new a class, there is memory allocated on the heap)_. Thats why their fields are on the heap.(even valuetyped fields). Only with structs (containing valuetyped fileds) are living on the stack when declared as local variable. – Jeroen van Langen Oct 14 '13 at 08:32
  • 1
    The values of value types, such as structs and what you call "trivial data types", are stored where they are declared, unless optimized. If they are declared as a local variable, they might be on the stack or in a register, unless they are declared in a closure, an iterator block or an async method (which really are classes). If they are declared as intance fields in a class, they will be stored in objects that live on one of the heaps. See also http://blogs.msdn.com/b/ericlippert/archive/2009/04/27/the-stack-is-an-implementation-detail.aspx – Kris Vandermotten Oct 14 '13 at 08:32
  • Of course the generated field will have a weird name like `k__BackingField` or something, at it will carry a `CompilerGeneratedAttribute`, but that's just details. Surely there is going to be a backing field of the same type as the auto-property. – Jeppe Stig Nielsen Oct 14 '13 at 08:35