Once a thing "escapes" from where it was created/initialized, it suddenly has a life cycle. Everything in that thing shares in that life cycle. It can cross multiple threads during that lifecycle. When that thing completes its life cycle is unbounded. Consequently, you can run out of intermediate resources (memory, file descriptors, database transactions, etc.) even though you would have enough if they could be reclaimed right now but you can't prove that you can do so.
This is one of the reasons why Rust exists and why it defaults to move semantics. Everything that you need to deallocate a thing is present at all times--you own the thing. If you borrow the thing, you cannot deallocate it. Life is good.
Sorta ...
Sometimes somebody else owns and controls the thing. Sometimes you initialize once and then everything is read-only from that point forward--synchronizing on a single runtime event gate. Not everything is memory and has bounded reclamation time. Sometimes things want different allocators and allocation strategies--you will reclaim some things every 16ms and some things very rarely. Sometimes you want to allocate on one thread and deallocate on another.
A lot of these don't fit RAII all that well because there is a time dimension to them rather than just space.
But then you have things like "reference counting" that's just an absolute nightmare to do without some mechanism like RAII. It's easy to always increment/decrement the reference count, but your performance is terrible--you need compiler elision of those for performance. I tried implementing a reference counted Scheme in C and Zig, and I wanted to blow my brains out from hunting all the reference counting bugs while C++/Rust would have been a breeze. Perhaps I just made a terrible architecture. ¯\_(ツ)_/¯
I'm not sure what the solution should be.
Rust took a very hard line about not paying runtime costs for things you don't use--that means lots of compile time effort, debug runs that are glacially slow, and blocking certain standard idioms behind "unsafe".
In reality, I'm actually willing to pay more at runtime than I thought as long as my runtime is deterministic. I'm willing to pay a bit at runtime to get a compiler that's two orders of magnitude faster whose debug code is only 25-50% slower than standard. I'm willing to pay at runtime for null and bounds checks. I've got a zillion cores doing nothing--giving up 10% to get a nicer language is perfectly acceptable to me.