Yes, ergonomics suck. It's particularly frustrating since a lot of things that end up pooled are confined to current thread execution (e.g. request) and could easily be stack alloc'd if that facility was there. Along the same lines, sharing messages across threads where one would simply like to memcpy into a ringbuffer become a pain in the rear.
Escape analysis hasn't lived up to its promises/potential, IMO. Current Hotspot uses control flow insensitive escape detection, meaning an object that escapes on any path, even if that path is never taken, is considered escaping. This can be improved to be CF sensitive, and Graal does that.
Secondly, beyond trivial examples, sufficient inlining needs to occur for compiler to have full horizon, and that can fail for a variety of reasons, even with run to run variance of exact same code shape.
As you say, there's no control and you're fully at the mercy of the compiler's mood that day. This is well into Sufficiently Smart Compiler land ...
The bottom line is that anyone for whom those allocations can be problematic take manual measures to ensure they don't happen and do not rely on EA.
Value types should help for a few reasons, however they appear to be somewhat limited (e.g. immutable, cannot be passed by ref).