The API for malloc is very simple:
void* malloc(size_t len);
void free(void* ptr);
Basically, ask for an amount of memory, and give back a pointer to memory. But it does not allow you communicate anything
but the amount on an allocation, and you can
only give a memory pointer on freeing. If, for example, malloc had an interface like:
void* malloc(size_t len, duration_t dur);
enum duration_t { SHORT, MEDIUM, LONG};
One can imagine you could optimize based on the given hint. Once you open up one kind of hint, you can imagine many other kinds of things users could communicate explicitly to the memory allocator about the allocation and access patterns of their data.
All implementations of free also need to find the related metadata for the given pointer. We could also imagine an interface for free which required the user to maintain that, but could perhaps speed things up:
void free(void* ptr, meta_t d);
Or, we could also imagine communicating how important it is to free this memory:
void free(void* ptr, immediacy_t im);
enum immediacy_t { IMMEDIATE, DELAYABLE };
In the latter case, maybe the memory allocator could put off doing delayable requests, and do them in a batch later. (Making it a bit more like garbage collection.)
I'm not sure any of these ideas would help, but the point is that because of the limited interface, we really can't explore them. We can, but then convincing the rest of the world to change such a basic building block of C code is quite hard.