Master C# Programming From Scratch

Clear, interactive, and structured coding lessons designed for absolute beginners.

Memory Basics in C#

What is Memory?

Memory is the area where a computer temporarily stores data and instructions while a program is running. When a C# application executes, the .NET runtime manages memory for objects, variables, method calls and other runtime information.

Understanding memory is important for C# developers because it helps us understand how variables are stored, how objects are created, how method calls work and how unused objects are eventually removed from memory.

Simple Idea: When a C# program runs, it needs memory to store the data required by the program. The .NET runtime manages much of this memory automatically.

Memory Management in .NET

The .NET runtime provides automatic memory management. Two important memory areas that beginners should understand are the Stack and the Heap.

Stack Heap
Used for method calls and local data. Used for dynamically allocated objects.
Works with a structured last-in-first-out model. Stores objects managed by the .NET runtime.
Generally fast to access. Managed by the Garbage Collector.
Method execution creates stack frames. Objects can remain in memory until they are no longer needed.

Stack Memory

The stack is used during method execution. Local variables, method parameters and information required for method calls are associated with stack frames.

When a method is called, a new stack frame is created for that method. When the method finishes execution, its stack frame is removed.

Example
C#
using System;
 
static void Calculate()
{
    int number = 10;

    Console.WriteLine(number);
}

Calculate();

Here, number is a local variable associated with the execution of the Calculate() method.

Heap Memory

The heap is used for objects that are dynamically created during program execution. In C#, objects created using new are generally allocated on the managed heap.

Example
C#
using System;
 
class Student
{
    public string Name;
}

Student student = new Student();

student.Name = "Rahul";

Console.WriteLine(student.Name);

The Student object is created using the new keyword and is managed by the .NET runtime.

Value Types and Memory

Value types directly contain their data. Common value types include int, double, bool, char, structures and enumerations.

C#
using System;
 
int number1 = 10;
int number2 = number1;

number2 = 20;

Console.WriteLine(number1);
Console.WriteLine(number2);
Output:
10
20

The second variable receives its own copy of the value. Changing number2 does not change number1.

Reference Types and Memory

Reference types store a reference to an object rather than directly containing the object's data. Classes, arrays, delegates and strings are examples of reference types.

C#
using System;

class Student
{
    public string Name;
}

class Program
{
    static void Main()
    {
        Student student1 = new Student();

        student1.Name = "Rahul";

        Student student2 = student1;

        student2.Name = "Amit";

        Console.WriteLine(student1.Name);
    }
}
Output: Amit

Both student1 and student2 refer to the same object. Therefore, changing the object through one reference can be observed through the other reference.

Memory During Method Calls

Whenever a method is called, the runtime needs to keep track of the method's parameters, local variables and execution information.

C#
using System;

static void Display(int number)
{
    int result = number * 2;

    Console.WriteLine(result);
}

Display(10);

During the execution of Display(), the runtime keeps track of the method parameter and local variable required by the method.

Understanding Reference Assignment

When one reference variable is assigned to another reference variable, a new object is not automatically created. Both variables can refer to the same object.

C#
using System;
 
class Car
{
    public string Model;
}

class Program
{
    static void Main()
    {
        Car car1 = new Car();

        car1.Model = "BMW";

        Car car2 = car1;

        car2.Model = "Audi";

        Console.WriteLine(car1.Model);
    }
}
Output: Audi

Object Lifetime

An object remains available as long as it can still be reached by references from the running application. When an object is no longer reachable, it may become eligible for garbage collection.

C#
using System;
 
class Employee
{
    public string Name;
}

Employee employee = new Employee();

employee.Name = "Rahul";

employee = null;

After the reference is assigned null, the object may become eligible for garbage collection if no other reference points to it.

What is Garbage Collection?

Garbage Collection, commonly called GC, is the automatic memory management feature provided by the .NET runtime.

The Garbage Collector identifies objects that are no longer reachable by the application and reclaims the memory used by those objects.

Important: Developers normally do not need to manually free managed memory. The .NET Garbage Collector handles this automatically.

Simple Garbage Collection Example

C#
using System;
 
class Student
{
    public string Name;
}

class Program
{
    static void Main()
    {
        Student student = new Student();

        student.Name = "Rahul";

        student = null;

        // The object may now become eligible
        // for garbage collection
    }
}

Managed and Unmanaged Resources

.NET automatically manages memory for managed objects. However, applications can also work with resources such as files, database connections, network connections and other resources that should be released properly.

For resources that implement IDisposable, the using statement is commonly used to ensure that the resource is disposed correctly.

C#
using (StreamWriter writer = new StreamWriter("data.txt"))
{
    writer.WriteLine("WelCome CIIT 🤓❤️...!");
}

The using statement ensures that the resource is disposed when execution leaves the block.

Memory Management Best Practices

  • Avoid creating unnecessary objects.
  • Release disposable resources properly.
  • Use using for objects that implement IDisposable.
  • Avoid keeping unnecessary references to large objects.
  • Understand the difference between value types and reference types.
  • Avoid manually forcing garbage collection unless there is a specific and well-understood reason.

Stack vs Heap - Quick Comparison

Feature Stack Heap
Purpose Method execution and local data Object storage
Management Managed automatically as methods execute Managed by the .NET Garbage Collector
Typical Use Method parameters and local variables Objects and dynamically allocated data
Lifetime Usually associated with method execution Depends on object reachability and GC
CIIT Practical Point: In interviews, candidates are commonly asked about Stack vs Heap, Value Type vs Reference Type, Garbage Collection, object lifetime and IDisposable.

Common Mistakes to Avoid

  • Assuming every variable is stored in exactly the same memory location.
  • Assuming assigning one reference variable to another automatically creates a new object.
  • Forgetting to dispose resources such as streams and database connections.
  • Calling GC.Collect() unnecessarily.
  • Confusing object lifetime with variable lifetime.
Summary

Memory management is an important concept in C#. The .NET runtime manages memory automatically. The Stack is associated with method execution and local data, while the managed Heap is used for objects. Understanding value types, reference types, object lifetime and Garbage Collection helps developers write efficient and reliable applications.

Practice Questions

  1. What is Stack memory?
  2. What is Heap memory?
  3. Explain the difference between Stack and Heap.
  4. What is the difference between Value Type and Reference Type?
  5. What happens when one reference variable is assigned to another?
  6. What is Garbage Collection?
  7. What is an unreachable object?
  8. What is IDisposable?
  9. Why is the using statement useful?
  10. Why should GC.Collect() generally not be called unnecessarily?