Stack and Heap refers to 2 distinct memory areas utilized by an executing program based on the data type of data that it deals at a point during its execution.
Stack is that part of memory that a program uses to keep track of its execution flow. For example it stores the currently executed method and its arguments. All latest data is stored on top and when its no longer needed its removed in a LIFO manner and a Garbage collection is not needed since the removal of unwanted data from the memory is done automatically as the program execution further down the road. All value types data (eg. all primitive data types that the programming language provides such as int, bool, float, long etc and as a exception, struct in C#) are stored in the stack memory. Struct data type – beware using it and use it safely and responsibly as it might cause unintended consequences if not used as intended 🙂 i.e its primary usage to bundle related value types and to be used a single unchanged entity or value. Its best to pass a struct by reference to save space in stack.
Heap is that part of memory where normally reference type data is stored in a structured manner. All non-primitive type data typed data (classes, string(C#), enum, arrays etc ) is stored in Heap memory. Data in heap is generally accessed via pointers that reside in stack memory or sometimes in heap. When we instantiate a class as obj1, obj2, two pointers are created in the stack for obj1 and obj2 memory locations residing on heap. We then use these pointers to access the object data residing on the heap. Now since the object data can have value typed data as members (eg: an int age value), technically a value typed data can reside in heap. The data in heap is not removed automatically by the program and the native programming system need to invoke its Garbage collection to get the unwanted heap data flushed out and repoint the pointers to active data. This usually affects performance since all threads need to be stopped. Also keep in mind to clone objects as opposed to copying them as it will end up giving same values for reference types which have to be modified after copy and we want to keep the modified values in both objects (tip – use ICloneable interface).
Keeping this distinction in mind, will help us to design and code high performance software systems.