FG
๐Ÿ“ก Networking

Empty rooms aren't deleted

Freshabout 21 hours ago
Mar 14, 20260 views
Confidence Score55%
55%

Problem

I noticed a possible memory leak, so I tested by connecting to my server from about a dozen client webpages and repeatedly refreshing them. Memory usage increased with each refresh and never fell back to pre-refresh levels. Turns out the unique rooms that are created for new connections aren't getting deleted โ€” they remain in the room list despite becoming empty upon refresh. Empty rooms are supposed to be destroyed automatically, so I don't know what's going on, but it might be why memory usage keeps rising. I tried explicitly deleting these rooms when a client disconnects. This removes them from the room list, but memory usage seems unaffected. I might be doing it wrong: [code block] Does this seem strange to anyone else? Is there another potential reason for the memory leak?

Unverified for your environment

Select your OS to check compatibility.

1 Fix

Canonical Fix
Unverified Fix
New Fix โ€“ Awaiting Verification

Implement Automatic Room Cleanup on Disconnect

Medium Risk

The memory leak occurs because empty rooms are not being properly cleaned up from the server's memory after clients disconnect. While rooms are removed from the room list, lingering references may prevent garbage collection, leading to increased memory usage. This can happen if there are event listeners or other references still attached to the room, preventing it from being fully deleted.

Awaiting Verification

Be the first to verify this fix

  1. 1

    Ensure Proper Room Cleanup on Disconnect

    Modify the disconnect event handler to not only remove the room from the room list but also to clean up any event listeners or references associated with that room. This will help ensure that the room can be garbage collected.

    javascript
    socket.on('disconnect', () => {
      const roomId = getRoomIdForSocket(socket);
      socket.leave(roomId);
      // Remove event listeners related to the room
      socket.removeAllListeners('message');
      // Optionally, check if the room is empty and delete it
      if (io.sockets.adapter.rooms[roomId] && io.sockets.adapter.rooms[roomId].length === 0) {
        delete io.sockets.adapter.rooms[roomId];
      }
    });
  2. 2

    Check for Event Listeners

    Ensure that any event listeners that may have been added to the room or socket are removed when the client disconnects. This can prevent memory leaks caused by lingering references.

    javascript
    socket.on('disconnect', () => {
      socket.removeAllListeners();
    });
  3. 3

    Implement Room Cleanup Logic

    Add logic to check if a room is empty before removing it. This can help ensure that rooms are only deleted when they are truly no longer in use.

    javascript
    function cleanupEmptyRooms() {
      for (const roomId in io.sockets.adapter.rooms) {
        if (io.sockets.adapter.rooms[roomId].length === 0) {
          delete io.sockets.adapter.rooms[roomId];
        }
      }
    }
    setInterval(cleanupEmptyRooms, 60000); // Run cleanup every minute
  4. 4

    Monitor Memory Usage

    After implementing the above changes, monitor the server's memory usage over time to ensure that it stabilizes after client disconnects. Use tools like Node.js memory profiling or logging to track memory usage.

    javascript
    setInterval(() => {
      console.log(process.memoryUsage());
    }, 5000); // Log memory usage every 5 seconds

Validation

To confirm the fix worked, connect multiple clients to the server and repeatedly refresh their connections. Monitor the server's memory usage before and after the changes. If memory usage stabilizes and does not increase with each refresh, the fix is successful.

Sign in to verify this fix

Environment

Submitted by

AC

Alex Chen

2450 rep

Tags

socket.iowebsocketrealtimebug