From: Eric Wong Date: 2018-03-23T16:55:10+00:00 Subject: [ruby-core:86265] idle lazy sweeping + stack depth tracking Hey all, I wonder if these ideas have been proposed, yet: 1) idle lazy sweeping Typical Ruby processes spend a fair amount of time waiting for I/O. With select/poll (and better, kqueue/epoll with green-threads), we can use a zero-timeout first, before using real timeout: while (!rc && is_lazy_sweeping() && most_threads_idle() && timeout != 0) { rc = poll(..., 0); /* no waiting, just a quick check */ if (rc == 0) { lazy_sweep_step(); /* call gc_sweep_continue */ } } if (!rc) { /* normal execution path */ rc = poll(..., timeout); } Maximum effectiveness would be gained by making all pipe/socket non-blocking by default (like 1.8) so it's easier to track I/O wait. 2) stack depth tracking for marking Building on above, but use an online algorithm to track average stack depth and bias the GC to start marking when poll (or similar function) sleeps when stack is shallow. Having the GC favor marking when the stack is shallow should reduce live objects and mark time. The online algorithm to track average stack depth will add some overhead, unfortunately. So I have more confidence in 1. The basic idea of both is to make sure the Ruby VM can always do cleanup work without introducing internal background threads and causing contention. I won't have time to implement, yet, maybe mid-April; but these will be MUCH easier after IO updates for green threads in https://bugs.ruby-lang.org/issues/13618 gets accepted because calling poll/ppoll/select repeatedly with the same FD sets is expensive and epoll/kqueue avoids that cost. Unsubscribe: