All Projects → bullno1 → Ugc

bullno1 / Ugc

Licence: bsd-2-clause
A single-header incremental garbage collector library

Programming Languages

c
50402 projects - #5 most used programming language

Projects that are alternatives of or similar to Ugc

cactusref
🌵 Cycle-Aware Reference Counting in Rust
Stars: ✭ 129 (-25.43%)
Mutual labels:  garbage-collection, memory-management
python-memory-management-course
Demo code exploring Python's memory models and collection algorithms from the Talk Python Training course.
Stars: ✭ 31 (-82.08%)
Mutual labels:  garbage-collection, memory-management
mmtk-core
Memory Management ToolKit
Stars: ✭ 205 (+18.5%)
Mutual labels:  garbage-collection, memory-management
Gc
Simple, zero-dependency garbage collection for C
Stars: ✭ 851 (+391.91%)
Mutual labels:  memory-management, garbage-collection
on-the-fly-gc
Concurrent mark-sweep garbage collector for accurate garbage collection of language runtimes in C++ 1x.
Stars: ✭ 25 (-85.55%)
Mutual labels:  garbage-collection, memory-management
Bdwgc
The Boehm-Demers-Weiser conservative C/C++ Garbage Collector (libgc, bdwgc, boehm-gc)
Stars: ✭ 1,855 (+972.25%)
Mutual labels:  garbage-collection, memory-management
Vulkanmemoryallocator
Easy to integrate Vulkan memory allocation library
Stars: ✭ 1,136 (+556.65%)
Mutual labels:  memory-management
Isoalloc
A general purpose memory allocator that implements an isolation security strategy to mitigate memory safety issues while maintaining good performance
Stars: ✭ 130 (-24.86%)
Mutual labels:  memory-management
Memreduct
Lightweight real-time memory management application to monitor and clean system memory on your computer.
Stars: ✭ 1,101 (+536.42%)
Mutual labels:  memory-management
Errand Boy
A memory-conscious alternative to os.fork() and subprocess.Popen().
Stars: ✭ 34 (-80.35%)
Mutual labels:  memory-management
Rmm
RAPIDS Memory Manager
Stars: ✭ 154 (-10.98%)
Mutual labels:  memory-management
Avoid Memory Leak Android
🔥 Examples of memory leaks and common patterns that cause them in Android development and how to fix/avoid them
Stars: ✭ 140 (-19.08%)
Mutual labels:  memory-management
Reading
A list of computer-science readings I recommend
Stars: ✭ 1,919 (+1009.25%)
Mutual labels:  garbage-collection
Automem
C++-style automatic memory management smart pointers for D
Stars: ✭ 71 (-58.96%)
Mutual labels:  memory-management
Memorypool
一个极简内存池实现
Stars: ✭ 131 (-24.28%)
Mutual labels:  memory-management
Weakable Self
A Swift micro-framework to easily deal with weak references to self inside closures
Stars: ✭ 64 (-63.01%)
Mutual labels:  memory-management
Heapinspector For Ios
Find memory issues & leaks in your iOS app without instruments
Stars: ✭ 1,819 (+951.45%)
Mutual labels:  memory-management
Go Pmem
Native persistent memory support for Go
Stars: ✭ 57 (-67.05%)
Mutual labels:  memory-management
Notes
let me know if my notes help you :D (it's a mess, I know)
Stars: ✭ 119 (-31.21%)
Mutual labels:  garbage-collection
Garbage Collection
🗑 Custom Home Assistant sensor for scheduling garbage collection (or other regularly re-occurring events - weekly on given days, semi-weekly or monthly)
Stars: ✭ 139 (-19.65%)
Mutual labels:  garbage-collection

μgc

License

μgc is a single-header garbage collector library. It is designed to be embedded in a programming language's runtime.

Features

  • Fully incremental using tri-color marking.
  • No external dependencies.
  • No memory allocation.
  • Overhead of 2 pointers per object.
  • Thoroughly tested: unit test and property-based test

Usage

Building

Put ugc.h into your project.

Write in one C file:

#define UGC_IMPLEMENTATION
#include "ugc.h"

Integrating with your runtime

All heap allocated objects must include ugc_header_t, usually as the first member:

struct my_heap_obj_s
{
	ugc_header_t header;

	// Other fields
	type_info_t type;
	void* external_ref;
	// ...
};

Initialize a garbage collector with:

ugc_t gc;

ugc_init(&gc, scan_fn, free_fn);

// Each gc instance has a userdata field.
gc.userdata = language_runtime;

ugc_init requires two callback functions: scan_fn and free_fn.

scan_fn is a function that will be called to help μgc trace an object's reference and the root set. It should behave as follow:

static void
scan_gc_obj(ugc_t* gc, ugc_header_t* header)
{
	if(header == NULL) // Scan the root set
	{
		// ugc_visit needs to be called on each pointer in the stack and global
		// environment

		struct my_language_runtime_s* runtime = gc->userdata;

		// Scan the stack
		for(unsigned int i = 0; i < runtime->stack_len; ++i)
		{
			if(runtime->stack[i]) { ugc_visit(gc, runtime->stack[i]); }
		}

		// If the language is similar to Lua where the global environment is a
		// first-class object, call ugc_visit on the object instead of its fields
		ugc_visit(gc, runtime->global);
	}
	else // Scan the given object
	{
		// ugc_visit needs to be called on each external reference of this
		// object.

		struct my_heap_obj_s* obj = (struct my_heap_obj_s*)header;
		if(obj->external_ref) { ugc_visit(gc, obj->external_ref); }
	}
}

The second parameter of ugc_visit must not be NULL and must point to a ugc_header_t.

free_fn will be called when μgc has determined that a language's object is garbage. It should release an object's resources:

static void
free_gc_obj(ugc_t* gc, ugc_header_t* header)
{
	struct my_language_runtime_s* runtime = gc->userdata;
	runtime->free(header);
}

When a new object is allocated, it needs to be registered with μgc using:

ugc_register(gc, new_object);

Whenever an object receives a reference to another (i.e: src.field = dst), μgc must be informed:

ugc_write_barrier(gc, direction, src, dst);

There are two types of write barriers: "forward" and "backward".

LuaJIT wiki states the following about "backward" barrier:

This is moving the barrier "back", because the object has to be reprocessed later on. This is beneficial for container objects, because they usually receive several stores in succession. This avoids a barrier for the next objects that are stored into it (which are likely white, too).

And "forward" barrier:

This moves the barrier "forward", because it implicitly drives the GC forward. This works best for objects that only receive isolated stores.

In the above language example, stores to the stack/local variables do not require a write barrier but stores to global variables do.

Controlling garbage collection

μgc does not start collection automatically because there are many factors (e.g: heap size, number of objects, time limit...) that need to be considered. It is best left to the language implementer to decide. Thus, it provides two functions to control the garbage collector:

ugc_step(gc) performs a single atomic step (e.g: mark/free one object, scan the root set). One typically calls it several times per allocation or regularly after a trigger. "Push/pop GC pause" function usually found in some language's API can be implemented by simply maintaining a counter and not calling ugc_step if it is non-zero. The current state of the GC is stored in ugc_t::state. One can use that to give different speeds to different phases.

ugc_collect(gc) finishes the current collection cycle. This means:

  • If the GC has alread started, it will return once the current cycle ends.
  • If the GC is idle (ugc_t::state == UGC_IDLE), it will start a cycle and finish it.

Therefore, if the GC is already in the UGC_SWEEP phase, any new garbage will be left to the next cycle. One needs to pay attention to this when calling gc_collect in case of emergency (e.g: malloc returns NULL). The first call to gc_collect may reclaim some but not all memory. It is possible for malloc to return NULL again. gc_collect should be called a second time. The runtime should only panic if malloc still fails.

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].