1

so I'm trying to find a memory leak in an app I've deployed to Heroku. I use express post requests in most if not all of my functions so I think there's some fundamental issue I'm missing here. Looking at the 'Closures' section of this link (https://betterprogramming.pub/the-4-types-of-memory-leaks-in-node-js-and-how-to-avoid-them-with-the-help-of-clinic-js-part-1-3f0c0afda268), it seems like you have to nullify variables to deallocate the memory they take up. Here is my function:

async function HelperFunction() {
  const client = await pool.connect()
  return new Promise( async (resolve, reject) => {
    let var0 = []
    let currentDate = new Date()
    let date = ("0" + currentDate.getDate()).slice(-2);
    let month = ("0" + (currentDate.getMonth() + 1)).slice(-2);
    let year = currentDate.getFullYear();
    let currentTimestamp = year + "-" + month + "-" + date + " " + hours + ":" + minutes + ":" + seconds
    try {
      await client.query('BEGIN')
      const res = await client.query(querySQLFunction, [currentTimestamp]);
      for (row of res.rows) {
          let jsonObject = {
            var1: row.var1,
            var2 : row.var2,
            var3 : Number(row.var3),
            var4 : Number(row.var4),
            var5 : 0
          }
          var0.push(jsonObject)
        }
      await client.query('COMMIT')
    } catch(err) {
      await client.query('ROLLBACK')
      console.log(err)
    } finally {
      client.release()
      resolve(var0)
    }
  })
}

So for example, in the above function, do I have to set all the lets to null in the 'finally' block? Also, if I define functions inside other functions:

async function otherFunction() {
    const foo = async (page) => {
        //await query some stuff
    }
    //nullification of foo here?
}

do I have to set the const's to null before the function is over?

nickcoding2
  • 142
  • 1
  • 8
  • 34
  • Related? [Why is last iteration of variable declared in for loop not getting garbage collected?](https://stackoverflow.com/q/67646525) – VLAZ Jun 03 '21 at 19:38
  • I'm not sure the memory leak is just coming from the for loop though--I have a suspicion it might be from the let variables above the for loop as well. @VLAZ – nickcoding2 Jun 03 '21 at 19:49
  • No, you don't. You may need to do this if a function modified variables in parent scope, which is not the case. The code contains promise constructor antipattern, but I don't think it can cause a leak – Estus Flask Jun 03 '21 at 21:38
  • @EstusFlask Okay good to know, thank you for your help! I'll keep searching for the root issue. – nickcoding2 Jun 03 '21 at 22:29
  • 2
    Unrelated, but [never pass an `async function` as the executor to `new Promise`](https://stackoverflow.com/q/43036229/1048572)! – Bergi Jun 03 '21 at 23:25
  • 1
    "*it seems like you have to nullify variables to deallocate the memory they take up*" - no, you don't. You just have to make sure they go out of scope (of anything that stays alive). To find your memory leak, make heap snapshots and look at what objects are retained unexpectedly. – Bergi Jun 03 '21 at 23:34
  • @Bergi After reading about promise antipattern, it seems like you can just return the function instead of using try/catch. So what exactly would that look like in this case? (I'm also assuming that the anti pattern is evident in HelperFunction(), but I'm having a tough time relating examples here (https://stackoverflow.com/questions/23803743/what-is-the-explicit-promise-construction-antipattern-and-how-do-i-avoid-it) to my code. – nickcoding2 Jun 04 '21 at 13:26
  • 1
    Yes, you should just remove the line `return new Promise( async (resolve, reject) => {` and replace `resolve(var0)` by `return var0`. As for what the problem is, consider what happens if `client.release()` throws or you have typo in the lines before the `try`. – Bergi Jun 04 '21 at 13:28
  • @Bergi Great, thank you--looking at my code now, anti pattern is evident through my entire backend. As a side note, is anti pattern just inefficient or can it cause actual errors? – nickcoding2 Jun 04 '21 at 13:40
  • 1
    Yes, it causes actual problems - when an error happens (in the wrong place), it doesn't reject the returned promise but causes an unhandled promise rejection (of the promise returned by the `async function`). – Bergi Jun 04 '21 at 13:44

0 Answers0