diff --git a/include/monitor.h b/include/monitor.h
index 102fe7e..2b638c6 100644
--- a/include/monitor.h
+++ b/include/monitor.h
@@ -14,13 +14,12 @@ struct rb_bh;
 
 struct monitor
 {
-	struct monitor *hnext;
 	char name[NICKLEN];
 	rb_dlink_list users;
+	rb_dlink_node node;
+	unsigned int hashv;
 };
 
-extern struct monitor *monitorTable[];
-
 #define MONITOR_HASH_BITS 16
 #define MONITOR_HASH_SIZE (1<<MONITOR_HASH_BITS)
 
diff --git a/modules/m_monitor.c b/modules/m_monitor.c
index a6ce575..11b45e8 100644
--- a/modules/m_monitor.c
+++ b/modules/m_monitor.c
@@ -181,6 +181,8 @@ del_monitor(struct Client *client_p, const char *nicks)
 
 		rb_dlinkFindDestroy(client_p, &monptr->users);
 		rb_dlinkFindDestroy(monptr, &client_p->localClient->monitor_list);
+
+		free_monitor(monptr);
 	}
 }
 
diff --git a/src/monitor.c b/src/monitor.c
index 280ef59..e9dac7d 100644
--- a/src/monitor.c
+++ b/src/monitor.c
@@ -37,7 +37,7 @@
 #include "hash.h"
 #include "numeric.h"
 
-struct monitor *monitorTable[MONITOR_HASH_SIZE];
+static rb_dlink_list monitorTable[MONITOR_HASH_SIZE];
 static rb_bh *monitor_heap;
 
 void
@@ -56,11 +56,13 @@ struct monitor *
 find_monitor(const char *name, int add)
 {
 	struct monitor *monptr;
+	rb_dlink_node *ptr;
 
 	unsigned int hashv = hash_monitor_nick(name);
 
-	for(monptr = monitorTable[hashv]; monptr; monptr = monptr->hnext)
+	RB_DLINK_FOREACH(ptr, monitorTable[hashv].head)
 	{
+		monptr = ptr->data;
 		if(!irccmp(monptr->name, name))
 			return monptr;
 	}
@@ -69,10 +71,9 @@ find_monitor(const char *name, int add)
 	{
 		monptr = rb_bh_alloc(monitor_heap);
 		rb_strlcpy(monptr->name, name, sizeof(monptr->name));
+		monptr->hashv = hashv;
 
-		monptr->hnext = monitorTable[hashv];
-		monitorTable[hashv] = monptr;
-
+		rb_dlinkAdd(monptr, &monptr->node, &monitorTable[hashv]);
 		return monptr;
 	}
 
@@ -82,6 +83,10 @@ find_monitor(const char *name, int add)
 void
 free_monitor(struct monitor *monptr)
 {
+	if (rb_dlink_list_length(&monptr->users) > 0)
+		return;
+
+	rb_dlinkDelete(&monptr->node, &monitorTable[monptr->hashv]);
 	rb_bh_free(monitor_heap, monptr);
 }
 
@@ -139,6 +144,8 @@ clear_monitor(struct Client *client_p)
 
 		rb_dlinkFindDestroy(client_p, &monptr->users);
 		rb_free_rb_dlink_node(ptr);
+
+		free_monitor(monptr);
 	}
 
 	client_p->localClient->monitor_list.head = client_p->localClient->monitor_list.tail = NULL;
