The correct answer applies to your problem area. But in the problem areas I work in, the first one is usually the one we choose.
I do in real time or next to a real time code. Audio editing and playback are mostly. In this code, we usually cannot afford to allocate memory from the heap in the playback engine. Most of the time, malloc returns quickly enough, but sometimes it is not. And that sometimes matters.
So, our solutions are to have specific pools for certain objects and use a common pool for everything else. In certain pools, a certain number of elements are pre-distributed and implemented as a linked list (actually a queue), so the distribution and release do not exceed a couple of pointer updates and the cost of entering and exiting a critical section.
As a reserve for unusual cases; when someone needs to be allocated from a special pool and it is empty, we will allocate a piece of shared memory (several objects) and add this to a special pool. When the allocation is part of a special pool, it will NEVER return to the shared pool until the application exits or launches a new project.
A good selection of the initial size and maximum size of special pools is an important part of customizing the application.
John knoeller
source share