facebookarchive / libphenom

An eventing framework for building high performance and high scalability systems in C.
http://facebook.github.io/libphenom
Apache License 2.0
1.66k stars 362 forks source link

Use custom memory allocator? #67

Closed jonathanmarvens closed 10 years ago

jonathanmarvens commented 10 years ago

Hi, @wez.

First of all, I just want to say thank you for this amazing library. I've been using libPhenom for a while now (almost close to a year) and we've building software with it at my startup for several months now. So yeah, thank you very much for your awesome work.

Right now, we have one little issue. We use jemalloc for almost all of our C code when it comes to memory management. Since we've been using libPhenom, we've avoided the memory utilities in order to use jemalloc. However, we really like the memory utilities and we feel we're missing out. I'm wondering if you'd consider adding a facility to the memory utilities to allow hooking a custom memory allocator?

In fact, if you'd be interested in that, I can work on a PR.

Please let me know! Much thanks!

- Jonathan

wez commented 10 years ago

Hi Jonathan,

Thanks :-)

We use jemalloc exclusively in our primary use of libphenom; we use jemalloc as a malloc replacement so no hooks are necessary; malloc(3C) and so on are the jemalloc versions of those functions.

Hookable allocators can add complexity and overheads that often prove to be more trouble than they're worth.

For example: having two different allocators in the same process space, especially modern caching allocators, makes it more difficult to for either of them to recognize low memory conditions and return memory to the system, or to make theoretically "free" memory that is cached in one allocator available to the other one.

Another source of issues with mingling allocators is ensuring that they are atomically applied early enough. For example, if the hook is simply a couple of global function pointers that can be changed at runtime, any memory allocations or frees that occur across the boundary of changing those functions becomes potentially dangerous: freeing memory across the boundary with the wrong allocator can lead to heap corruption or segfaults. The risk of this is higher if the application uses ctor/dtors to register initialization and finalization functions per source module (as libphenom does), because the ctors can run in an unpredictable order, and have dependencies that require allocating memory.

I'm not opposed to this kind of thing, having wished that many libraries made this more transparent in the past, but want to make sure that the end goal can't be more easily accomplished elsewhere in the application before taking this complexity into libphenom.

So, with that big fat disclaimer out of the way: I welcome your feedback on making libphenom better for your use-case, especially if you're willing to lay down code too. Before we get to coding, can you tell me a bit more about how you're using jemalloc and why using it as a global malloc replacement doesn't work for you? How do you envision the allocator override working?

Thanks!

--Wez.

jonathanmarvens commented 10 years ago

Hi, @wez!

I apologize for the really really long delay to actually reply back. I've been really busy this past month :( . That's probably more of an excuse than anything, though.

Thanks so much for the detailed response. I really value and appreciate you putting your time into that! So, I took your suggestion and we actually ended up just hooking up jemalloc globally. Everything is fine. It turns out my main worries about hooking it up globally were both superficial and due to not fully understanding how jemalloc hooks itself up in the system.

Again, thanks so much for your time and suggestions. Had you not questioned that, I likely wouldn't have gone that route. I also managed to learn a few things because of this ... which is always a good thing, I think :smile:.

I hope you're well! Thanks!

- Jonathan

wez commented 10 years ago

Hi Jonathan, No problem re: delay, just glad that you solved this and happy to have helped :-)