I wrote a small "bad example" program for a presentation. It calls malloc/free very frequently and I wanted to profile the impact of this compared to a pool allocator solution. Unfortunately I had to notice that the program only runs for a fraction of a second before deadlocking. As it seems the following situation accurs:

1) Thread 1 calls malloc(), and locks the internal malloc mutex
2) Thread 2 triggers garbage collection and stops thread 1
3) Thread 2 is done collecting garbage and calls all destructors. One of these calls free(), as the malloc mutex is still locked by Thread 1 and Thread 1 will never release the mutex, as it is stoped, Thread 2 deadlocks.

Now this is not limited to malloc / free, it can happen with any kind of locking that is done within a destructor.

Currently I can only think of two ways to fix this:

1) Don't use free inside a destructor (goodbye manual memory management)
2) A callback triggered by the GC before it starts stopping any threads, and after it is done destructing all objects to manually lock / unlock necessary synchronization primitives to prevent this kind of deadlocking. The default implementation of this callback should lock / unlock the malloc mutex.

--
Kind Regards
Benjamin Thaut

Reply via email to