Freelist implementation of MemoryPool

This patch changed the implementation of MemoryPool from block cache to free lists. It tries to allocate multiple memory blocks at once to further reduce fragmentation. This heavily impacts memory pool initialization time but still provides almost equivalent overall performance compared to the original implementation.