There are plenty of soft and hard real-time GCs though suitable for use with any GC'd language. For instance, the CHICKEN collector in [1] is an absurdly simple copying collector with an observed maximum pause time of 120 microseconds with average pauses of 1 microsecond.
Low-latency GC tends to sacrifice a little throughput though, which is why it's not more widely used. Relative to a standard concurrent MS, CHICKEN adds up to 30% in execution time, although the average seems to hover around 10-15%.
[1] ftp://ftp.inf.ufrgs.br/pub/geyer/PDP-Pos/Artigos/PDP-2011-2-TL1-artigos/PDP-2011-2-TL1-GT-A%20Study%20of%20Concurrent%20Real-Time%20Garbage%20Collectors.pdf
Soft/hard realtime was always a spectrum and basically the point of hard-realtime is never reached in practice (if your hardware dies or glitches you miss your deadline, caches are hard to model but you't want to switch them off etc).
Even without changed VM one can enforce garbage collection at certain points which moves Erlang on the throughput/realtime spectrum more towards realtime. Not worth it if a non realtime OS schedules you but of value when controlling exactly who can preempt you (under RTEMS no-one is feasible)