preface

This is an article to record the memory leakage problems encountered on the work and how to solve the article.

Problem description

Let me outline my problem:

Technology stack: Framework: VUE Component Library: Ant Design of Vue Chart: G2.

Project requirements: In the kanban below, you need to toggle the two small blue dots below every 20 seconds to toggle and refresh the chart. The premise is that polling tools such as Web sockets are not used.

The following component structure: Switch-flex-chart component is composed of flex-Chart component and switch-icon-card component. By adding a timer to switch-Icon-card component (namely two small blue dots), Changes index every 20 seconds and calls back to the parent component (switch-flex-chart) to refresh and change the chart data in the Flex-Chart component.

The problem: It was fine at first, but over time it would make the page very sluggish, but in the code, I would clear the timer and set it to NULL every time during the life-destruction-phase

First, the timer should be cleared in time

Instead of using setInterval for polling, I used two settimeouts:

<template></template>

<script>
export default {
  created() {
        this.init()
  },
  mounted() {},
  data() {
    return{duration: 20000, _timer: null // timer}}, methods: {init() {// initializeif (this.duration > 0) {
          this._timer && clearTimeout(this._timer)
          this._timer = null
          this.polling()
        }
    },
    autoPlay() {// Switch function... },polling () {
        this._timer = setTimeout(() => {this.autoplay () this._timer && clearTimeout(this._timer) this.polling()}, this.duration) } } } </script>Copy the code

In the code above, I used clearTimeout to clear the timer every time I polling polling, but I found that the timer was still executing silently when you switched to another page, so I thought I must also destroy the timer every time the component is destroyed:

destroyed() {// Life cycle - component destroy this._timer && clearTimeout(this._timer) // Use clearTimeout this._timer = null // It is better to set the timer to null as well}Copy the code

2. Chart data should be cleared in time

The above solution solves the problem that the switch page timer is still running, but it still does not solve the problem that the page will be very slow. Normally, this is not a problem even if the timer runs for a long time. So there must be a memory leak somewhere.

To see if this was the case, I opened Chrome’s F12 console. Then I found Memory:

Here you can take a heap snapshot of JavaScript objects and look for memory leaks.

At this point I record a snapshot every 10 seconds for snapshot1-3, and notice that the total size of JavaScript objects is getting bigger and bigger every time, and soon my browser will freeze up.

The first thing I thought about was whether the contents of the chart were not cleared, so I executed the g2 built-in method destory() for destruction every time I drew the G2 chart.

<template></template>

<script>
export default {
  created() {
        this.init()
  },
  mounted() {},
  data() {
    return {
        chart: null
    }
  },
  methods: {
      init () {
        ifChart = new G2.Chart({this.chart){this.chart = new G2.Chart({... }) } } </script>Copy the code

Thinking I was done, I opened the browser again and found that the memory leak had not been fixed. So I wondered if the graph object should also act like a timer, freeing memory when it is destroyed.

Try it:

destroyed () {
    this.chart.destroy()
    this.chart = null
}
Copy the code

After that, I recorded three snapshots again, this time with no growth in the size of the JavaScript object, and my page hung for half an hour without any signs of stalling.

Afterword.

While the problem is fixed, I’m not sure why using this.chart.destroy() on initialization doesn’t free memory, instead of using null. Google g2 destory() and it pops up a bunch of G2 in LOL…

Thanks to OBKoro1 for his help.

Reference article:

Talk about a memory leak I had during front-end development

Garbage collection mechanism in JS elevation and common solutions to memory leaks