Garbage Collection and Compaction

 

๐Ÿงน Garbage Collection and Compaction

1. What is Garbage Collection?

Garbage Collection is the process of identifying and reclaiming memory that is no longer in use by any program.

  • After a process releases memory (explicitly or automatically), that memory becomes "garbage" if not reclaimed.

  • Garbage collection frees up this memory so that it can be used for new allocations.

Key idea: Automatically clean unused memory blocks.


✨ Example:

Suppose memory blocks are:

Block Address        Size        Used/Free
1000        200        Used
1200        150        Free
1350        300        Used
1650        100        Free
1750        200        Free
Garbage collection will identify blocks at 1200, 1650, and 1750 as free memory.

2. What is Compaction?

Compaction is the process of rearranging memory contents so that all free memory is combined together into one large block.

  • After garbage collection, free blocks may be scattered.

  • Compaction moves used memory blocks together and pushes free space to one side.

Key idea: Minimize fragmentation and maximize continuous free memory.


✨ Example (after compaction):

Initially:


[Used 200][Free 150][Used 300][Free 100][Free 200]

After Compaction:


[Used 200][Used 300][Free 450]
  • All free space becomes one large block of 450 KB.


๐ŸŽฏ Why are Garbage Collection and Compaction Important?

  • Avoids memory leaks.

  • Ensures large memory blocks are available.

  • Improves system performance.

  • Essential in systems like Java Virtual Machine (JVM) and Operating Systems.


๐Ÿง  Linked List Representation

  • Each memory block = one node.

  • Fields:

    • Start Address

    • Size

    • Status (Used or Free)

    • Pointer to next block

    • Pointer to previous block


๐Ÿ”ต C Program: Garbage Collection and Compaction using doubly Linked List

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

// Define structure for memory block (Doubly Linked List)
struct Block {
    int start_address;
    int size;
    int is_free; // 1 if free, 0 if used
    struct Block* prev;
    struct Block* next;
};

struct Block* head = NULL;

// Create a new block
struct Block* create_block(int start, int size, int is_free) {
    struct Block* new_block = (struct Block*)malloc(sizeof(struct Block));
    new_block->start_address = start;
    new_block->size = size;
    new_block->is_free = is_free;
    new_block->next = NULL;
    new_block->prev = NULL;
    return new_block;
}

// Add block to the end
void add_block(int start, int size, int is_free) {
    struct Block* new_block = create_block(start, size, is_free);

    if (head == NULL) {
        head = new_block;
        return;
    }

    struct Block* temp = head;
    while (temp->next != NULL) {
        temp = temp->next;
    }

    temp->next = new_block;
    new_block->prev = temp;
}

// Display memory blocks
void display_memory() {
    struct Block* temp = head;
    printf("\nMemory Blocks:\n");
    printf("----------------------------\n");
    while (temp != NULL) {
        printf("Start: %d, Size: %d, Status: %s\n",
               temp->start_address,
               temp->size,
               temp->is_free ? "Free" : "Used");
        temp = temp->next;
    }
    printf("----------------------------\n");
}

// Garbage collection: merge adjacent free blocks
void garbage_collection() {
    struct Block* temp = head;

    while (temp != NULL && temp->next != NULL) {
        if (temp->is_free && temp->next->is_free) {
            // Merge with next
            temp->size += temp->next->size;
            struct Block* to_delete = temp->next;
            temp->next = to_delete->next;

            if (to_delete->next != NULL) {
                to_delete->next->prev = temp;
            }

            free(to_delete);
        } else {
            temp = temp->next;
        }
    }
}

// Compaction: move used blocks to front, merge all free blocks
void compaction() {
    struct Block* new_head = NULL;
    struct Block* last_used = NULL;
    int current_address = 1000;

    // Move used blocks
    struct Block* temp = head;
    while (temp != NULL) {
        if (!temp->is_free) {
            struct Block* new_block = create_block(current_address, temp->size, 0);
            current_address += temp->size;

            if (new_head == NULL) {
                new_head = new_block;
                last_used = new_head;
            } else {
                last_used->next = new_block;
                new_block->prev = last_used;
                last_used = new_block;
            }
        }
        temp = temp->next;
    }

    // Calculate total free space
    int free_size = 0;
    temp = head;
    while (temp != NULL) {
        if (temp->is_free) {
            free_size += temp->size;
        }
        temp = temp->next;
    }

    if (free_size > 0) {
        struct Block* free_block = create_block(current_address, free_size, 1);
        if (new_head == NULL) {
            new_head = free_block;
        } else {
            last_used->next = free_block;
            free_block->prev = last_used;
        }
    }

    // Free old memory list
    temp = head;
    while (temp != NULL) {
        struct Block* next = temp->next;
        free(temp);
        temp = next;
    }

    head = new_head;
}

int main() {
    // Initial memory setup
    add_block(1000, 200, 0); // Used
    add_block(1200, 150, 1); // Free
    add_block(1350, 300, 0); // Used
    add_block(1650, 100, 1); // Free
    add_block(1750, 200, 1); // Free

    printf("\nBefore Garbage Collection and Compaction:");
    display_memory();

    garbage_collection();
    printf("\nAfter Garbage Collection:");
    display_memory();

    compaction();
    printf("\nAfter Compaction:");
    display_memory();

    return 0;
}

Output
Before Garbage Collection and Compaction:
Memory Blocks:
--------------------------------------------
Start: 1000, Size: 200, Status: Used
Start: 1200, Size: 150, Status: Free
Start: 1350, Size: 300, Status: Used
Start: 1650, Size: 100, Status: Free
Start: 1750, Size: 200, Status: Free
---------------------------------------------

After Garbage Collection:
Memory Blocks:
--------------------------------------------
Start: 1000, Size: 200, Status: Used
Start: 1200, Size: 150, Status: Free
Start: 1350, Size: 300, Status: Used
Start: 1650, Size: 300, Status: Free
----------------------------------------------

After Compaction:
Memory Blocks:
--------------------------------------------
Start: 1000, Size: 200, Status: Used
Start: 1200, Size: 300, Status: Used
Start: 1500, Size: 450, Status: Free
--------------------------------------------

Comments

Popular posts from this blog

Data Structures and Algorithms PCCST303 KTU 2024 Scheme- Dr Binu V P

Performance Analysis - Time and Space Complexity

Data Structures and Data Abstraction