When you're working in a GCed language you assume your language's GC is responsible for freeing memory. When you interoperate with a language where owners are responsible for freeing memory, you have to have a way to "disown" structures you've created but passed into the ownership language (e.g. a callback you've passed to a library function) so that your GC doesn't free them, and a way to "own" structures you've received from the ownership language (e.g. values returned from library functions) so that your GC does free them, and neither of these things will be easy/natural in your language.
When you interoperate with another GCed language it's even harder, virtually impossible, because both languages' GCs assume they own everything and so anything that's visible in both languages will be freed twice.
I've done it in Java; it's not officially supported in the language standard (or has only recently been added if so - certainly they were talking about it for years), and the wider language does not generally have the support or idioms you would want (e.g. try-with-resources was only introduced a couple of versions ago), libraries aren't oriented towards that style.... It's certainly doable but I'd stand by it not being easy or natural.
When you interoperate with another GCed language it's even harder, virtually impossible, because both languages' GCs assume they own everything and so anything that's visible in both languages will be freed twice.