Potential memory leaks

This paper is participating in thePerformance optimization combat record”Topic essay activity

The introduction

What is a memory leak?

If memory that is no longer needed by a system process is not released in time, it is called a memory leak. As memory usage increases, it can affect system performance at best or cause process crashes at worst. The perspective from the front. Poorly written JavaScript can cause memory leaks that are subtle and harmful:

  • White screen/black screen
  • Lag/slow page loading
  • Flash retreat/fever
  • 💥

Which operations cause memory leaks

Accidentally declare global variables

Accidental declarations of global variables are one of the most common and easily solved memory leaks. Properties created on the window do not disappear as long as the window itself is not cleared. Unable to release clean effectively

  1. The code
function t(){
   name = 'renlingxin'
}
The //name variable will hang on the window and the window variable will not be destroyed until the window closes or the page is refreshed
// let const var instead

Copy the code
  1. Other mount

Plug-in/business scenarios sometimes use properties mounted to Windows to enable different projects to communicate with each other in the running environment for example

  1. WebView / JavaScript
  2. Cocos / JavaScript
  3. SDK – A / SDK – B
  4. .

We need proper mounts. Avoid mounting large volumes of data.

Second, the closure

function d(){
  let name = 'renlingxin'
  return function r(){
    console.log(name)
  }
}
// This will cause memory allocated to name to leak. If the name is large. It would be a big problem.

Copy the code

Three, timer (timely clear)

Maintain good code habits.


<template>
 <div>{{ timeDom }}</div>
</template>

<script>
  mounted() {
    this._time = setInterval(() => {
      this.timeDom  = new Date()
    }, 1000);
  },
  // beforeDestroy 销毁之前的定时器
  beforeDestroy() {
    clearInterval(this._time)
  }
</script>

Copy the code

4. Event listeners (e.g. Vue eventBus)

Import eventBus from './eventBus' export default {mounted() {eventBus.$on('page-change', () => { console.log('page-change triggered! ')})}, beforeDestroy() {// Remove eventBus listener eventBus.$off('page-change')}}Copy the code

Variables and Dom reference each other

Let’s look at an example:

  1. Execute Node — expose-GC on the console
> process.memoryUsage()
{
  rss: 143835136.heapTotal: 5054464.heapUsed: 3446128.external: 1668772.arrayBuffers: 9917
}
> let y = new Array(5*1024*1024)//1. Create a 5*1024*1024 array
undefined
> let g = {d:y,g:'renlingxin'} //2. Set key -d in g to y to establish strong reference relationships
undefined
> process.memoryUsage()  //3. Check that the current memory size is about 43.48 MB
{
  rss: 325320704.heapTotal: 47263744.heapUsed: 45596216.external: 1668828.arrayBuffers: 9933
}
> y = g.d = null  // 4. Set y and g.d to null to dereference
null
> global.gc()   // 5. Manually trigger a GC collection
undefined
> process.memoryUsage() // 6. Memory is reduced to around 3.02 MB
{
  rss: 140541952.heapTotal: 5316608.heapUsed: 3171248.external: 1668812.arrayBuffers: 9917
}

Copy the code

From this we can conclude the importance of cross-referencing variables and proactively releasing references to trigger GC collection

  1. WeakMap/weakSet can be used to establish weak reference relationships
> process.memoryUsage()  //1. The initial memory size is about 3.28 MB
{
  rss: 144654336.heapTotal: 5054464.heapUsed: 3447472.external: 1668772.arrayBuffers: 9917
}
> let t = new WeakMap(a)/ / 2. New WeakMap
undefined
> let y = new Array(5*1024*1024) //3. Create a 5*1024*1024 array
undefined
> t.set(y,'333')   // 4. Set y to WeakMap
//WeakMap { <items unknown> }
> process.memoryUsage() // 5. The current memory size is about 43.22M
{
  rss: 329957376.heapTotal: 47001600.heapUsed: 45320184.external: 1668824.arrayBuffers: 9929
}
> global.gc()  // 6. Actively trigger gc collection
undefined
> process.memoryUsage() //7. The memory has no change
{
  rss: 332529664.heapTotal: 47263744.heapUsed: 45110040.external: 1668812.arrayBuffers: 9917
}
> y = null // empty the original y value to null. However, we do not empty the y in t
null
> global.gc() // 9. Free memory
undefined
> process.memoryUsage() //10. The memory size is about 3.07M
{
  rss: 161005568.heapTotal: 5316608.heapUsed: 3227656.external: 1668815.arrayBuffers: 9920
}

Copy the code

Console (The browser will remember the output variable. Avoid online environment printing)

uglifyjs-webpack-plugin / transform-remove-console … And other methods can be used to remove the log

A debugging tool

A, the Performance

Comprehensive performance monitoring tool

Noun explanation

  • Summary: Time occupied by indicators
  • Bottom-up: indicates the sorted event duration list
  • Call Tree: List of events called in sequence
  • Event Log: Indicates the sequence list of events

Ps: When your Js Heap has a trend like this. There is a risk of memory leaks

Second, the Memory

The snapshot function

  1. Began to take pictures

  2. Delete all

  3. Function:

    • Summary – Displays objects sorted by constructor name;
    • Comparison – shows the difference of objects between two snapshots;
    • Containment – used to probe heap contents;
  4. The Constructor represents all objects generated by the Constructor

  5. Distance Indicates the Distance to the GC root object. The GC root object is typically a Window object in browsers and a global object in Node.js

  6. The Shallow Size column shows the total number of Shallow sizes(which directly hogs memory) of the object generated by the corresponding constructor – the size of the object itself, not including the bytes it references

  7. The Retained size column shows the maximum memory used by the Retained object —- The size of the object itself and the size of the referenced object, that is, the memory that can be reclaimed after GC. It’s in bytes

  8. Memory type

    • Compiled code indicates the Compiled code
    • A closure closure
    • HTMLDivElement, HTMLAnchorElement, DocumentFragment, and so on are all references to elements or specified DOM objects in your code

    .

Third, the Performance monitor

Real-time monitoring tools. Reference indicators are JavaScript memory/CPU usage/DOM nodes/event listening…

conclusion

The topic of memory leaks doesn’t come up very often on the front end. Most business scenarios are simple page H5 development. But memory management is especially important for scenarios with complex logic/precipitation/animation. And many of the causes of memory leaks are the accumulation of problems. Cause the accumulated situation. Therefore, we need to pay attention to memory management from the daily write code.