I'm going to get flamed for this but...
C++ is hands down better than Java on the stack unwinding front--there's just no contest. C++ object destructors fire all the way back up the stack until the catch point is reached--releasing all managed resources gracefully along the way.
As you said, Java leaves all of this at the mercy of the non-deterministic garbage collector (worst case) or in the hands of whatever explicitly crafted finally blocks you've littered your code with (since Java doesn't support true RAII). That is, all the resource management code is in the hands of the clients of each class, rather than in the hands of the class designer where it should be.
That said, in C++, the stack unwinding mechanism only functions properly if you're careful to ensure that destructors themselves do not emit exceptions. Once you've got two active exceptions, your program abort()
's without passing go (and of course without firing any of the remaining destructors).