A single-file C allocator with explicit heaps and tuning knobs (github.com)

53 points by enduku 3 days ago

enduku 3 days ago

I wrote this because I wanted more explicit control over heaps when building different subsystems in C. Standard options like jemalloc and mimalloc are incredibly fast, but they act as black boxes. You can't easily cap a parser's memory at 256MB or wipe it all out in one go without writing a custom pool allocator.

Spaces takes a different approach. It uses 64KB-aligned slabs, and the metadata lookup is just a pointer mask (ptr & ~0xFFFF).

The trade-off is that every free() incurs an L1 cache miss to read the slab header, and there is a 64KB virtual memory floor per slab. But in exchange, you get zero-external-metadata regions, instant teardown of massive structures like ASTs, and performance that surprisingly keeps up with jemalloc on cross-thread workloads (I included the mimalloc-bench scripts in the repo).

It's Linux x86-64 only right now. I'm curious if systems folks think this chunk API is a pragmatic middle ground for memory management, or if the cache-miss penalty on free() makes the pointer-masking approach a dead end for general use.

throwaway2027 7 hours ago

When dealing with memory in C defaulting to malloc or some opaque structure behind it is unless you just want to allocate and forget it for some one off program that frees memory on proc exit seems bad to me now. For any kind of sophisticated system or module you almost always want to write your own variety of slab, arena, pool, bump whatever it may be allocator.

bitbasher 7 hours ago

There's a single commit in the whole repository. Was this AI generated?

skippyboxedhero an hour ago

Elements of the readme are a dead giveaway.

I can also tell you that this was written with Claude.

No issues with that in principle but I definitely would not trust Claude to get this stuff correct. Generally, it is quite bad at this kind of thing and usually in ways that are not obvious to people without experience.

varispeed an hour ago

sebazzz 7 hours ago

You still have things like git squash etc.

bitbasher 7 hours ago

ntoslinux 6 hours ago

What is the reason for the weird `{ code };` blocks everywhere and is the below code machine generated?

```c ((PageSize) (chunk->pageSize - ((PageSize) ((PageSize) ((PageSize) (sizeof(Page) + (sizeof(struct _Block))) + (PageSize) ((sizeof(double)) - 1u)) & ((PageSize) (~((PageSize) ((sizeof(double)) - 1u)))))) - ((PageSize) ((PageSize) ((PageSize) ((sizeof(FreeBlock) + sizeof(PageSize))) + (PageSize) (((((sizeof(double)) > (4)) ? (sizeof(double)) : (4))) - ```

bitbasher 6 hours ago

There's a lot of code in the file that is questionable to say the least. There are unnecessary blocks ( { ... }; ) of code with unnecessary semicolons that don't serve any logical purpose.

My hunch tells me it may be the result of macro-expansion in C (cc -E ...), etc. So it's likely there's a larger code base with multiple files and they expanded it into a one large C file (sometimes called an amalgamation build) and called it a day.

By they, I mean the OP, a script or an AI (or all three).

motbus3 5 hours ago

Exactly my thought... This look like a clean room implementation situation

mzajc 5 hours ago

Worse yet, there's several places with empty code blocks, eg. [0] and [1]. Even without that, the formatting contains so much unnecessary whitespace, newlines, casts, etc; I'm not sure why, given the already massive source file. How do you even fit [2] on a screen?

[0]: https://github.com/xtellect/spaces/blob/422dbba85b5a7e9a209a...

[1]: https://github.com/xtellect/spaces/blob/422dbba85b5a7e9a209a...

[2]: https://github.com/xtellect/spaces/blob/422dbba85b5a7e9a209a...

HexDecOctBin 7 hours ago

The classic Doug Lee's memory allocator[1] has explicit heaps by the name of mspaces. OP, were you aware of that; and if yes, what does your solution do better or different than dlmalloc's mspaces?

[1] https://gee.cs.oswego.edu/pub/misc/?C=N;O=D

motters 3 hours ago

As a long time C coder I checked this out, because I have my own malloc replacement. The source code is nonsensical garbage.

xantronix 2 hours ago

Brother. What is up with the Makefile rule 'test'? I don't mean to be harsh but is this performance art?

Edit: Homie. Why is bench.sh fetching external resources? Call me old fashioned, but it would be nice if when I cloned the repository (and checked out any submodules that may exist), I've got everything I need, right there.

lstodd 4 hours ago

Zig got this right to such a degree that I'm sometimes tempted to export its allocators to C via FFI. Then I sober up a bit and just rewrite it all in zig, all its instability nonwithstanding.

dnautics 3 hours ago

<semi-self-promotion> Not only that, since there is a super-standard std allocator api, it makes itself very amenable to memory safety analysis, as long as you don't sneakily implement allocations outside of that api.

https://github.com/ityonemo/clr

lstodd 3 hours ago

Now this is very interesting. Thank you for sharing.

swetland 2 hours ago

There is no way this utter pile of slop was written by a human.

jeffbee 4 hours ago

"That costs ~5 ns when the line is cold"

I don't see how that could possibly be true. Sounds like a low-ball estimate.

Also i wish to point out that the "tcmalloc" being used as a baseline in these performance claims is Ye Olde tcmalloc, the abandoned and now community-maintained version of the project. The current version of tcmalloc is a completely different thing that the mimalloc-bench project doesn't support (correctly; I just checked).