D
D
dollar2019-04-23 15:17:14
JavaScript
dollar, 2019-04-23 15:17:14

What is the memory leak in the code?

Profiler
5cbf006d6cdea282694185.png
Function code where the problem is
const MAX_DB_TIMEOUT = 60000;
let saveDB_timer;
let db_saved_called;
function saveDB(no_pause) {
  let now = (new Date()).getTime();
  db_saved_called = db_saved_called || now;
  if (saveDB_timer !== undefined) clearTimeout(saveDB_timer);
  function saveDB_Now() {
    //let check1 = performance.now();
    for(let i=0;i<db_clean_steps.length;i++) {
      clean_db(db_clean_steps[i]);
      try {
        localStorage.db = JSON.stringify(db);
        break;
      } catch(e) {
        console.log("Can't save DB");
      }
    }
    db_saved_called = undefined;
    //let check2 = performance.now();
    //console.log('DB_SAVED!', (check2-check1)+'мс');
  }
  if ((now - db_saved_called > MAX_DB_TIMEOUT) || no_pause) saveDB_Now();
  else saveDB_timer = setTimeout(saveDB_Now,15000);
}
The jump is observed at the end of the saveDB_Now() function. In theory, we simply replace the localStorage.db variable, which is not even an object, but a string. But suddenly it turns out that the memory remains somewhere. How so?
If it helps, here is another clean_db() function code, but it apparently has nothing to do with it
const db_clean_steps = [7, 3, 2, 1, 0.5, 0.2];
function clean_db(timeout_days) {
  const timeout = timeout_days *24*60*60*1000;
  //remove pending status
  for(let id in db.user) {
    if (!db.user[id]) {
      delete db.user[id];
      continue;
    }
    delete db.user[id].solutions_pending;
    delete db.user[id].karma_pending;
  }
  //remove users
  let now = (new Date()).getTime();
  for(let id in db.user) {
    let user = db.user[id];
    if (!(now - user.update_time < timeout)) delete db.user[id]; // n days
  }
  //remove questions
  for(let id in db.question) {
    let q = db.question[id];
    //ignore subscribtions
    if (q.sub) {
      if (!(now - q.ut < 400 * 24 * 60 * 60000)) delete db.question[id]; // 1 year
      continue;
    }
    //ut means update_time
    if (!(now - q.ut < timeout)) delete db.question[id]; // n days
  }
}

Here is the most interesting thing: it is clearly visible that while JSON.stringify() is running for about 20ms, some kind of wild magic happens with memory allocation. What kind of phenomenon is this?
Magic
5cbf17a68a079174520025.png

Answer the question

In order to leave comments, you need to log in

1 answer(s)
D
dollar, 2019-04-23
@dollar

The problem turned out to be much deeper. Namely - in the V8 engine .
That is, it only applies to Chrome and Node js.
It took a long time to dig. And the problem has not yet been solved, we have to study this bug and get around it in all places of the program (and there are a lot of them).
There is not enough information in the question, for that I apologize.
And the profiler is difficult to use, since the GC cleans the memory with large delays. Charts are not to be trusted.

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question