{"id":25074926,"url":"https://github.com/nathancordeiro/automatic-garbage-collector","last_synced_at":"2025-03-31T19:47:29.775Z","repository":{"id":252808257,"uuid":"841523437","full_name":"NathanCordeiro/Automatic-Garbage-Collector","owner":"NathanCordeiro","description":"For most C programs, manual memory management with malloc/free remains the standard approach. Garbage collection is more commonly used in higher-level languages like Java, Python, or Go, where the benefits of automatic memory management often outweigh the costs. ","archived":false,"fork":false,"pushed_at":"2025-01-28T10:28:10.000Z","size":57,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-02-07T00:20:15.641Z","etag":null,"topics":["c","garbage-collection","memory-management"],"latest_commit_sha":null,"homepage":"","language":"C","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/NathanCordeiro.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2024-08-12T15:19:38.000Z","updated_at":"2025-01-28T10:28:14.000Z","dependencies_parsed_at":"2025-01-28T11:25:14.327Z","dependency_job_id":"be8cb5f1-ae7f-483b-a8dc-cfc9b09acef0","html_url":"https://github.com/NathanCordeiro/Automatic-Garbage-Collector","commit_stats":null,"previous_names":["nathancordeiro/automatic-garbage-collector"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/NathanCordeiro%2FAutomatic-Garbage-Collector","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/NathanCordeiro%2FAutomatic-Garbage-Collector/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/NathanCordeiro%2FAutomatic-Garbage-Collector/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/NathanCordeiro%2FAutomatic-Garbage-Collector/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/NathanCordeiro","download_url":"https://codeload.github.com/NathanCordeiro/Automatic-Garbage-Collector/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":246531983,"owners_count":20792735,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["c","garbage-collection","memory-management"],"created_at":"2025-02-07T00:19:40.208Z","updated_at":"2025-03-31T19:47:29.755Z","avatar_url":"https://github.com/NathanCordeiro.png","language":"C","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Automatic-Garbage-Collector : HeapSweep\n---\nFor most C programs, manual memory management with malloc/free remains the standard approach. Garbage collection is more commonly used in higher-level languages \nlike Java, Python, or Go, where the benefits of automatic memory management often outweigh the costs.\n\nThe main motivation for creating a garbage collector is to simplify memory management in C programs. C is a powerful language, but it requires manual memory management, which can lead to issues like memory leaks, dangling pointers, and double frees. These problems can be difficult to debug and can cause program crashes or unpredictable behavior.\n\nWhile not suitable for production use, this project serves as an excellent learning tool for understanding garbage collection concepts and how they can be implemented in a low-level language like C.\n\nThe implementation is intentionally kept simple to make it easy to understand and modify. This makes it a good starting point for further experimentation or for educational purposes. \n\nThe project uses a simple yet effective garbage collection algorithm. It works in two phases:\n\n- Mark: Starting from known root objects (those on the stack), it traverses and marks all reachable objects.\n- Sweep: It then goes through all objects in the heap, freeing those that weren't marked.\n\n## License\n[![Licence](https://img.shields.io/github/license/Ileriayo/markdown-badges?style=for-the-badge)](./LICENSE)\n\n\n## Comparison of Memory Management Methods\n\n| **Aspect**                                | **Manual Memory Management (malloc/free)**                                                                 | **Reference Counting**                                                                                      | **Region-Based Memory Management**                                                                         | **HeapSweep**                                                                 |\n|-------------------------------------------|------------------------------------------------------------------------------------------------------------|------------------------------------------------------------------------------------------------------------|------------------------------------------------------------------------------------------------------------|------------------------------------------------------------------------------------------------|\n| **Memory Allocation/Deallocation**        | Programmer explicitly allocates and frees memory                                                           | Each allocation has a count of references to it                                                            | Allocations are grouped into regions                                                                       | Automatically reclaims memory that's no longer in use                                           |\n| **Error Prone**                           | Prone to memory leaks, use-after-free, and double-free errors                                              | Can't handle cyclic references without additional mechanisms                                               | Can lead to holding onto memory longer than necessary                                                      | Prevents common memory-related errors                                                          |\n| **Control**                               | Gives fine-grained control over memory usage                                                               | -                                                                                                          | -                                                                                                          | Less control over exact timing of memory deallocation                                          |\n| **Runtime Overhead**                      | No runtime overhead for tracking objects                                                                   | Overhead for maintaining counts                                                                            | -                                                                                                          | Adds some runtime overhead for tracking and collecting garbage                                 |\n| **Cyclic References**                     | -                                                                                                          | Can't handle cyclic references                                                                             | -                                                                                                          | Can handle cyclic references                                                                   |\n| **Reference Counts**                      | -                                                                                                          | Memory is freed when reference count drops to zero                                                         | -                                                                                                          | No need to update reference counts                                                             |\n| **Bulk Allocations/Deallocations**        | -                                                                                                          | -                                                                                                          | Entire regions are freed at once                                                                           | May be less efficient for bulk allocations/deallocations                                       |\n| **Efficiency**                            | -                                                                                                          | -                                                                                                          | Efficient for certain patterns of allocation/deallocation                                                  | Potentially more efficient for highly interconnected data structures                           |\n| **Flexibility**                           | -                                                                                                          | -                                                                                                          | -                                                                                                          | More flexible for general-purpose use                                                          |\n\n\n## Using HeapSweep in your project\n\n1. Include the files:\n   Add `simple_gc.h` and `simple_gc.c` to your project.\n\n2. In your main C file, include the header:\n   ```c\n   #include \"simple_gc.h\"\n   ```\n3. Initialize the GC heap at the start of your program:\n   ```c\n   GCHeap heap;\n   initGCHeap(\u0026heap);\n   ```\n\n4. Instead of using malloc for data that should be garbage collected, use the GC functions:\n   ```c\n   // Instead of: int* x = malloc(sizeof(int));\n   GCValue* x = createIntValue(\u0026heap, 42);\n\n   // Instead of: struct pair* p = malloc(sizeof(struct pair));\n   GCValue* p = createPairValue(\u0026heap, x, NULL);\n   ```\n\n5. Use `pushValue` and `popValue` to manage the root set (e.g., for local variables that shouldn't be collected):\n   ```c\n   pushValue(\u0026heap, x);\n   // ... do some work ...\n   popValue(\u0026heap);\n   ```\n\n6. You don't need to call free on GC-managed values. The GC will handle it.\n\n7. You can manually trigger garbage collection if needed:\n   ```c\n   collectGarbage(\u0026heap);\n   ```\n\n8. Clean up at the end of your program:\n   ```c\n   freeGCHeap(\u0026heap);\n   ```\n\n\n\n## Advantages and Disadvantages of HeapSweep\n\nBenefits:\n\n- Automatic memory management reduces cognitive load on programmers\n- Helps prevent memory leaks and use-after-free bugs\n- Can handle complex data structures with cyclic references\n- Allows for more natural expression of certain algorithms\n\nDrawbacks:\n\n- Added runtime overhead for GC operations\n- Less predictable memory usage and deallocation timing\n- May not be suitable for real-time or memory-constrained systems\n\n\n\n## Some examples of HeapSweep\n\n`Factorial of a number:`\n```c\n#include \"simple_gc.h\"\n#include \u003cstdio.h\u003e\n\nGCValue* factorial(GCHeap* heap, int n) {\n    if (n \u003c= 1) {\n        return createIntValue(heap, 1);\n    }\n    \n    GCValue* n_minus_one = factorial(heap, n - 1);\n    pushValue(heap, n_minus_one);  // Protect from GC\n    \n    GCValue* result = createIntValue(heap, n * n_minus_one-\u003eintValue);\n    popValue(heap);  // n_minus_one no longer needed\n    \n    return result;\n}\n\nint main() {\n    GCHeap heap;\n    initGCHeap(\u0026heap);\n\n    int n = 5;\n    GCValue* result = factorial(\u0026heap, n);\n    printf(\"Factorial of %d is %d\\n\", n, result-\u003eintValue);\n\n    collectGarbage(\u0026heap);\n    freeGCHeap(\u0026heap);\n    return 0;\n}\n```\n\n`Pointer demonstration creating array like structures:`\n```c\n#include \"simple_gc.h\"\n#include \u003cstdio.h\u003e\n\nvoid swapValues(GCHeap* heap, GCValue** a, GCValue** b) {\n    GCValue* temp = *a;\n    *a = *b;\n    *b = temp;\n}\n\nint main() {\n    GCHeap heap;\n    initGCHeap(\u0026heap);\n\n    GCValue* value1 = createIntValue(\u0026heap, 10);\n    GCValue* value2 = createIntValue(\u0026heap, 20);\n\n    pushValue(\u0026heap, value1);\n    pushValue(\u0026heap, value2);\n\n    printf(\"Before swap: value1 = %d, value2 = %d\\n\", value1-\u003eintValue, value2-\u003eintValue);\n\n    swapValues(\u0026heap, \u0026value1, \u0026value2);\n\n    printf(\"After swap: value1 = %d, value2 = %d\\n\", value1-\u003eintValue, value2-\u003eintValue);\n\n    // Create a pointer to a pointer (simulating a 2D array)\n    GCValue* array[2];\n    array[0] = createPairValue(\u0026heap, createIntValue(\u0026heap, 1), createIntValue(\u0026heap, 2));\n    array[1] = createPairValue(\u0026heap, createIntValue(\u0026heap, 3), createIntValue(\u0026heap, 4));\n\n    pushValue(\u0026heap, array[0]);\n    pushValue(\u0026heap, array[1]);\n\n    printf(\"2D array: [%d, %d], [%d, %d]\\n\",\n           array[0]-\u003epairValue.head-\u003eintValue, array[0]-\u003epairValue.tail-\u003eintValue,\n           array[1]-\u003epairValue.head-\u003eintValue, array[1]-\u003epairValue.tail-\u003eintValue);\n\n    collectGarbage(\u0026heap);\n    freeGCHeap(\u0026heap);\n    return 0;\n}\n```\n\n`Linked list demonstrating creating and manipulating complex data structures:`\n```c\n#include \"simple_gc.h\"\n#include \u003cstdio.h\u003e\n\nvoid printList(GCValue* head) {\n    GCValue* current = head;\n    while (current != NULL \u0026\u0026 current-\u003etype == VALUE_PAIR) {\n        printf(\"%d -\u003e \", current-\u003epairValue.head-\u003eintValue);\n        current = current-\u003epairValue.tail;\n    }\n    printf(\"NULL\\n\");\n}\n\nint main() {\n    GCHeap heap;\n    initGCHeap(\u0026heap);\n\n    // Create a linked list: 1 -\u003e 2 -\u003e 3 -\u003e 4 -\u003e 5\n    GCValue* list = NULL;\n    for (int i = 5; i \u003e= 1; i--) {\n        GCValue* newNode = createPairValue(\u0026heap, createIntValue(\u0026heap, i), list);\n        pushValue(\u0026heap, newNode);  // Protect from GC\n        list = newNode;\n    }\n\n    printf(\"Original list: \");\n    printList(list);\n\n    // Remove the second element (2)\n    if (list != NULL \u0026\u0026 list-\u003epairValue.tail != NULL) {\n        list-\u003epairValue.tail = list-\u003epairValue.tail-\u003epairValue.tail;\n    }\n\n    printf(\"List after removing second element: \");\n    printList(list);\n\n    collectGarbage(\u0026heap);\n    freeGCHeap(\u0026heap);\n    return 0;\n}\n```\n\n---\n\n![Last Stargazer](https://img.shields.io/badge/Last%20Stargazer-wldhks1959-brightgreen?style=flat-square)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnathancordeiro%2Fautomatic-garbage-collector","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fnathancordeiro%2Fautomatic-garbage-collector","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnathancordeiro%2Fautomatic-garbage-collector/lists"}