In a lot of use cases, like the drivers mentioned above, you shouldn't allocate on the heap anyway, whether manually or in a managed way. And if you don't allocate, you never need to garbage collect (since you never need to reclaim memory to make it available for new allocations). In that case, the two are even.
(The above assumes that GC is only triggered by allocations. Many GCs are like that, but others trigger periodically even if there isn't anything to do. I don't know which group OCaml is in.)
You heap allocate all the time in drivers. You just shouldn't do it from interrupt context. Source: I write plenty of drivers for a living.
And even if the GC is only triggered by allocations, they'll still pause the other contexts in order to scan their stacks for live references. So, in the case of a unikernel, you can end up with critical paths being paused by allocations outside the critical path.
> You heap allocate all the time in drivers. You just shouldn't do it from interrupt context. Source: I write plenty of drivers for a living.
Fair enough. I was thinking of low-level things like "shovel a few bytes from some hardware component into a user-provided buffer" without allocating anything, you seem to be working on more high-level drivers.
For a driver, you have many contexts you're running. That's what the windows error "IRQL not less than or equal" blue screen means, that someone called a regular kernel function from within interrupt context. In drivers, you almost always heap allocate in your non interrupt contexts in order to dynamically handle load. This would be even more necessary in a unikernel, where you don't have a user space to defer that kind of work to.
What I'm saying is that the necessary heap allocations happening in other contexts will block progress of your non allocating critical path, irq code on a GC based unikernel because of the need to discover liveness information. There are potential schemes to fix this, but they aren't implemented by MirageOS/OCaml, or most other managed unikernel environments I've seen.
(The above assumes that GC is only triggered by allocations. Many GCs are like that, but others trigger periodically even if there isn't anything to do. I don't know which group OCaml is in.)