Alavudeen
Alavudeen

Reputation: 89

Memory allocation on object creation

how much memory it will be allocated in stack as well as in heap when we instantiate the class/struct Student?

I guess id = 4 bytes reference (32 bit machine) and name = 4 bytes reference and facultyAdvisor = 4 bytes reference. So totally 12 bytes in stack and actual size will be in heap. this heap size may vary depends upon the value that we assign to the fields(id, name, facultyAdvisor) that uses object obj(Student obj = new Student())

The same is for struct also right?

public class Student { int id; string name; Professor facultyAdvisor; }

public struct Student { int id; string name; Professor facultyAdvisor; }

Upvotes: 4

Views: 2584

Answers (3)

Jon Skeet
Jon Skeet

Reputation: 1504132

First note that the stack and the heap are implementation details... as is the size of the object. But in the current implementation, all the data for the fields within Student when it's a class are on the heap. There's an object overhead as well as the memory taken for the fields, but all of that will be on the heap.

If you're keeping a reference to the new instance, and you're keeping it in an uncaptured local variable not in an iterator block or async method, that reference would be on the stack (in the current implementation) so it would be 4 bytes on a 32-bit CLR.

When Student is a struct, things change somewhat:

  • The location of the data (stack or heap) depends on how the value is being used - if it's stored in an instance variable in a class, for example, it will be on the heap along with the rest of the data; if it's in a local variable (again, uncaptured and not in an iterator block or async method) then it'll be on the stack
  • You're not creating a separate object, just a value, so there's no extra overhead - it really would just take 12 bytes (assuming Professor is a reference type)

I have a couple of articles/posts you may find useful:

EDIT: Addressing the Professor issue, assuming Professor is a class - unless a Professor object is explicitly created, the reference in Student will simply be null. Creating a new Student does not automatically create a new Professor just because there's a field of that type. The reference to the Professor is just part of the data for Student - it lives wherever the id lives - so if Student is a class, then the reference only exists on the heap, and if Student is a struct then it depends on where the Student value is created, as listed above.

Upvotes: 5

Richard Blewett
Richard Blewett

Reputation: 6119

Assuming 32 bit CLR (references would be 64 bit on 64 bit CLR) and only taking into account heap allocation for Student

class Student{} class Professor{}

  • Stack: 4 bytes
  • Heap: 4 bytes (int) + 4 bytes (Professor Reference) + 4 bytes (string reference) + 12 bytes (object header) = 24 bytes

class Student{} struct Professor{}

  • Stack: 4 bytes
  • Heap: 4 bytes (int) + size of Processor + 4 bytes (string reference) + 12 bytes (object header) = ?? bytes

struct Student{} class Professor{}

  • Stack: 4 bytes (int) + 4 bytes (string reference) + 4 bytes (Professor reference) = 12 bytes
  • Heap: 0 bytes

struct Student{} struct Professor{}

  • Stack: 4 bytes (int) + 4 bytes (string reference) + size of Professor = ?? bytes
  • Heap: 0 bytes

Upvotes: 1

Dyppl
Dyppl

Reputation: 12381

You can use GC.GetTotalMemory(true) calls to measure memory consumption before and after instantiation to measure heap allocation

Upvotes: 1

Related Questions