Tom
Tom

Reputation: 6707

Objects memory leaks (Heroku to 1.5 GB memory usage when nodejs is configured to max 512M)

The code is very simple and it should free objects from the memory, there are about 20 concurrent users in this app.

The idea of code is that sessionID is the key to store object, and when session ends the object is freed.

CODE

'use strict'
const http = require('http')
const app = require('./config')
const Server = http.Server(app)
const PORT = process.env.PORT || 8000
const io = require('socket.io')(Server)

Server.listen(PORT, () => console.log('Game server running on:', PORT))

const players = {}
const moneys = {} 

var util = require('util');

io.on('connection', socket => {
    // When a player connects
    socket.on('new-player', state => {
    //console.log(socket.id+'New player joined with state:', state)
    players[socket.id] = state
    // Emit the update-players method in the client side
    io.emit('update-players', players)

    var pCount = Object.keys(players).length;
    console.log("players in mem "+pCount);      
  });

   socket.on('new-money', state => {
      moneycounter++
      moneys[socket.id] = state
      // Emit the update-players method in the client side
      if (moneycounter >2) {
          io.emit('update-moneys', moneys)
          moneycounter = 0
      }
  });

  socket.on('disconnect', state => {
      console.log(socket.id+' player discontinue with state:', state)

    try {
        if (typeof players[socket.id].playerName != 'undefined') delete players[socket.id].playerName
        if (typeof players[socket.id].speed != 'undefined') delete players[socket.id].speed
    }
    catch (err) {
        console.log(socket.id+' typeerror deleting 1')
    }
    delete players[socket.id]
    delete moneys[socket.id]
     //  io.emit('update-players', players)
  });

  // When a player moves
  socket.on('move-player', data => {
    //console.log(' move player' +socket.id)
    const { x, y, angle, playerName, speed } = data

    // If the player is invalid, return
    if (players[socket.id] === undefined) {
       console.log(socket.id+' invalid move')

      try {
         if (typeof players[socket.id].playerName != 'undefined') delete players[socket.id].playerName
         if (typeof players[socket.id].speed != 'undefined') delete players[socket.id].speed
       }
       catch (err) {
          console.log(socket.id+' typeerror 3 deleting')
       }

       delete players[socket.id]
       delete moneys[socket.id]
       socket.disconnect();
       return
    }

    // Update the player's data if he moved
    players[socket.id].x = x
    players[socket.id].y = y
    players[socket.id].angle = angle
    players[socket.id].playerName = {
      name: playerName.name,
      x: playerName.x,
      y: playerName.y
    }
    players[socket.id].speed = {
      value: speed.value,
      x: speed.x,
      y: speed.y
    }

    // Send the data back to the client
    io.emit('update-players', players)
  })
})

For some reason my app that takes in very begin ~20mb ram but later same day takes over 1.5GB causing memory R14 errors.

heroku 2hours log

My config should limit it to 512 like this:

web node --optimize_for_size --max_old_space_size=460 --gc_interval=100 server/index.js

My current config is 2X. (1024 mb plan)

Is there an option to configure heroku to restart if memory error R14 occurs.

Upvotes: 3

Views: 1181

Answers (1)

Abhishek Singh
Abhishek Singh

Reputation: 2727

You can use node-memwatch package to monitor for the memory leak and when there is a memory leak you can restart the app from the code itself.

Restart a node.js app from code level

Upvotes: 4

Related Questions