Empty rooms aren't deleted
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
Implement Automatic Room Cleanup on Disconnect
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
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.
javascriptsocket.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
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.
javascriptsocket.on('disconnect', () => { socket.removeAllListeners(); }); - 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.
javascriptfunction 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
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.
javascriptsetInterval(() => { 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
Alex Chen
2450 rep