Same for other responses. Great, you can just implement a lifespan array in every subsystem. If your sub systems are very simple (e.g. single Entity component is the only thing you're allocating in a game, maybe Resource as well), then sure, its simple. Not sure what it's buying you, since you apparently are also freeing all entities and scene elements at once too. But for a complex system where there are many types of objects (dozens or hundreds), and where lifespans are complex (some short, some long), then having "every system implement its own pool" adds a lot of complexity. Then not only would you want type-safety with a Handle<Object> for every type of object, but also some kind of affinity for the sub-system which currently manages that lifespan (unless you just have a single Pool for every object type, which re-introduces the lifespan issues).
Again, other responses I'll lump into "sounds like for simple systems it isn't substantially more difficult than pointers". I guess if it has a meaningful performance tradeoff, then it might be worth it (where a simple free list or using system malloc would be too expensive).
If you say you don't need many objects, so counters can be small, and you never need to resize the handles array, so indexes are valid, and you don't have lots of object types, and don't have lots of subsystems, and lifespans are purely scoped to subsystem lifespans, and don't mind type bloat all over your interfaces, then it sounds like handles are a perfect fit. I'm trying to imagine what's so bad about using pointers in such a simple system, and what we're "solving" (e.g. just &memory_array[next_index++]).