diff --git a/src/ruby/ext/grpc/rb_grpc.c b/src/ruby/ext/grpc/rb_grpc.c
index eefdb93d6734b7c30afdca549301f0e0cdce2822..1f887d69b5e1aca0533c497e2e7c902f6086388c 100644
--- a/src/ruby/ext/grpc/rb_grpc.c
+++ b/src/ruby/ext/grpc/rb_grpc.c
@@ -269,20 +269,10 @@ static void Init_grpc_time_consts() {
   id_tv_nsec = rb_intern("tv_nsec");
 }
 
-/*
-   TODO: find an alternative to ruby_vm_at_exit that is ok in Ruby 2.0 where
-   RUBY_TYPED_FREE_IMMEDIATELY is not defined.
-
-   At the moment, registering a function using ruby_vm_at_exit segfaults in Ruby
-   2.0.  This is not an issue with the gRPC handler.  More likely, this was an
-   in issue with 2.0 that got resolved in 2.1 and has not been backported.
-*/
-#ifdef RUBY_TYPED_FREE_IMMEDIATELY
-static void grpc_rb_shutdown(ruby_vm_t *vm) {
-  (void)vm;
+static void grpc_rb_shutdown(VALUE val) {
+  (void)val;
   grpc_shutdown();
 }
-#endif
 
 /* Initialize the GRPC module structs */
 
@@ -308,10 +298,7 @@ void Init_grpc_c() {
 
   grpc_init();
 
-/* TODO: find alternative to ruby_vm_at_exit that is ok in Ruby 2.0 */
-#ifdef RUBY_TYPED_FREE_IMMEDIATELY
-  ruby_vm_at_exit(grpc_rb_shutdown);
-#endif
+  rb_set_end_proc(grpc_rb_shutdown, Qnil);
 
   grpc_rb_mGRPC = rb_define_module("GRPC");
   grpc_rb_mGrpcCore = rb_define_module_under(grpc_rb_mGRPC, "Core");