I'm personally a fan of regular old Java/C#-like concurrent garbage collection for most "scripting" languages (perhaps surprisingly, given my work on Rust). It's a lot of work to get there, but I think there's no substitute for doing the work—apps really end up needing the flexibility of shared memory. Shortcuts that seem simple like DRC end up tending to run into walls in practice, which is something that the other languages discovered—history keeps pointing to the HotSpot-style garbage collector as the one that systems that need to offer a simple, general-purpose garbage-collected programming model migrate to.
For different use cases Rust-style ownership semantics (when the performance of GC and runtime interoperability become an issue), or Azul-style pauseless GC (when you're willing to trade throughput for latency), or shared-nothing architectures (when you need them for legacy reasons like JavaScript, or want a simple programming model like Erlang) can work great.