Unref uv timers/tcp handles
diff --git a/src/core/lib/iomgr/tcp_uv.cc b/src/core/lib/iomgr/tcp_uv.cc
index f20f8dc..8d0e4a5 100644
--- a/src/core/lib/iomgr/tcp_uv.cc
+++ b/src/core/lib/iomgr/tcp_uv.cc
@@ -204,6 +204,9 @@
   uv_socket->write_buffers = nullptr;
   uv_socket->read_len = 0;
   uv_tcp_nodelay(uv_socket->handle, 1);
+  // Node uses a garbage collector to call destructors, so we don't
+  // want to hold the uv loop open with active gRPC objects.
+  uv_unref((uv_handle_t*)uv_socket->handle);
   uv_socket->pending_connection = false;
   uv_socket->accept_socket = nullptr;
   uv_socket->accept_error = GRPC_ERROR_NONE;
diff --git a/src/core/lib/iomgr/timer_uv.cc b/src/core/lib/iomgr/timer_uv.cc
index dadeb96..8b7c82e 100644
--- a/src/core/lib/iomgr/timer_uv.cc
+++ b/src/core/lib/iomgr/timer_uv.cc
@@ -52,6 +52,9 @@
   uv_timer->data = t;
   t->timer = (void*)uv_timer;
   uv_timer_start(uv_timer, run_expired_timer, t->timeout_ms, 0);
+  // Node uses a garbage collector to call destructors, so we don't
+  // want to hold the uv loop open with active gRPC objects.
+  uv_unref((uv_handle_t*)uv_timer);
 }
 
 static void timer_stop(grpc_custom_timer* t) {