Table of Contents
Overview
Garbage collection mechanism
Reference counting method
The disadvantages of the above reference counting method are already obvious, so now we are going to talk about the marking clearing method There is no such problem. Because the judgment standard it uses is to see whether the object
内存泄漏
闭包
定义与特性
系列目录
一张纸懂JS系列(1)之编译原理,作用域,作用域链,变量提升,暂时性死区" >一张纸懂JS系列(1)之编译原理,作用域,作用域链,变量提升,暂时性死区
一张纸搞懂JS系列(2)之JS内存生命周期,栈内存与堆内存,深浅拷贝" >一张纸搞懂JS系列(2)之JS内存生命周期,栈内存与堆内存,深浅拷贝
一张纸搞懂JS系列(3)之垃圾回收机制,内存泄漏,闭包
Home Web Front-end JS Tutorial Understand the garbage collection mechanism, memory leaks, and closures of JS series (3) with one piece of paper

Understand the garbage collection mechanism, memory leaks, and closures of JS series (3) with one piece of paper

Sep 30, 2020 pm 04:38 PM
memory leak Garbage collection mechanism Closure

javascriptThe column introduces the garbage collection mechanism, memory leaks, and closure contents. Let’s take a look at the fast-end bench.

Understand the garbage collection mechanism, memory leaks, and closures of JS series (3) with one piece of paper

Write at the front: This is a series I am about to start writing in the javascript column, mainly in the framework of rampant In the era, although I use a framework for work, for interviews and technical advancement, the basic knowledge of JS is the icing on the cake, and it is also a piece of knowledge that I have to learn. Although you don’t need to know a lot about cars to drive a car, you only need to master the common uses of cars. Just function. But if you know cars, you can drive better, and by the same token. Of course, an article will not just talk about one knowledge point. Generally, related knowledge points will be connected in series. While recording your own learning, you will share your own learning and encourage each other! If you can, please also please give me a like, your likes will also make me work harder to update!

Overview

  • Eating time: 6-12 minutes
  • Difficulty: Easy, don’t run, watch before leaving

Garbage collection mechanism

The previous blog mainly explains the allocation and use of memory (stack memory and heap memory, deep copy and shallow copy). After use, of course, Returning unused memory is like clearing unused software on your phone from the background, which can improve the running speed of your phone. Otherwise, if more and more memory is used, it will get stuck sooner or later. The same goes for JS.

Every once in a while, the garbage collector of JS will "patrol" the variables, just like security patrols in the park, letting irrelevant people leave quickly . When a variable is no longer needed, it will release the memory space occupied by the variable. This process is called Garbage Collection

JS Garbage There are two types of recycling algorithms, reference counting and mark clearing.

  • Reference counting method

    The reference counting method is the most basic garbage collection algorithm and has been used by modern browsers. The equipment has been eliminated. Before learning the reference counting method, you need to first have a certain concept of reference. You can think of it as a description of the memory address pointed to by the current variable, which is somewhat similar to the memory pointer of the JS reference data type. To understand the concept, let’s first look at a line of code:

    var obj={name:'jack'};复制代码
    Copy after login

    When we assign a value to obj, we actually create a reference pointing to the variable, reference count is 1, Under the mechanism of reference counting, each value in the memory will correspond to a reference count

    , and when we assign a value to obj, it is When null, this variable becomes a piece of useless memory. At this time, the reference count of obj will become 0, and it will be garbage collected. The memory space occupied by obj will be released

    We know that the life cycle of the function scope is very short. After the function is executed, the memory space inside Variables are basically useless variables. The consequence of not clearing them is that the memory garbage is not released, and it still occupies the original memory and does not let go, which will easily cause memory leak. Let’s first look at a piece of code and Running results:

    function changeName(){   var obj1={};   var obj2={};
       
       obj1.target=obj2;
       obj2.target=obj1;
       obj1.age=15;   console.log(obj1.target);   console.log(obj2.target);
    }
    
    changeName();复制代码
    Copy after login
    Understand the garbage collection mechanism, memory leaks, and closures of JS series (3) with one piece of paper
    ##We can see that
    obj1.target and obj2.target have mutual references. situation, because when obj1.age is changed, obj1.target.age and obj2.target.age are also affected at the same time, and they point to The reference count is consistent When the function is executed,

    obj1 and obj2 are still alive and well, because obj1.target and ## After the execution of #obj2.target is completed, the reference count is still 1. It is clear that the function has been executed, but this kind of garbage still exists. There are too many such functions defined, Memory leakIt will also be unavoidable

  • Mark clearing method
  • The disadvantages of the above reference counting method are already obvious, so now we are going to talk about the marking clearing method There is no such problem. Because the judgment standard it uses is to see whether the object

    can be reached

    , it is mainly divided into two stages, marking stage and clearing stage:

      Marking phase
    • The garbage collector will start from the root object (Window object) and scan all reachable objects. This is the so-called

      reachable

    • Clear phase While scanning, objects that cannot be reached by the root object (
    • unreachable

      ) are objects that are considered unnecessary and will be cleared as garbage

    现在再来看下上面的代码

    function changeName(){    var obj1={};  var obj2={};
      
      obj1.target=obj2;
      obj2.target=obj1;
      obj1.age=15;  console.log(obj1.target);  console.log(obj2.target);
    }
    
    changeName();复制代码
    Copy after login

    在函数执行完毕之后,函数的声明周期结束,那么现在,从 Window对象 出发, obj1obj2 都会被垃圾收集器标记为不可抵达,这样子的情况下,互相引用的情况也会迎刃而解。

内存泄漏

该释放的内存垃圾没有被释放,依然霸占着原有的内存不松手,造成系统内存的浪费,导致性能恶化,系统崩溃等严重后果,这就是所谓的内存泄漏

闭包

  • 定义与特性

    闭包是指有权访问另一个函数作用域中的变量的函数。至于为什么有权访问,主要是因为作用域嵌套作用域,也就是所谓的作用域链,关于作用域链不清楚的可以看我的第一篇博客一文搞懂JS系列(一)之编译原理,作用域,作用域链,变量提升,暂时性死区,就是因为作用域链的存在,所以内部函数才可以访问外部函数中定义的变量 ,作用域链是向外不向内的,探出头去,向外查找,而不是看着锅里,所以外部函数是无法访问内部函数定义的变量的。并且,还有一个特性就是将闭包内的变量始终保持在内存中。

    前面的作用域向外不向内,这里就不再做过多解释了,我们主要来看我后面说的特性,那就是闭包内的变量始终保存在内存中

    来看一下阮一峰教程当中的一个例子

     function f1(){     var n=999;
    
         nAdd=function(){n+=1}     function f2(){         console.log(n);
         }     return f2;
    
     } var result=f1();     //等同于return f2();
    
     result(); // 999
    
     nAdd();
    
     result(); // 1000
     nAdd();
    
     result(); // 1000复制代码
    Copy after login

    从输出结果就可以看得出来,这个变量 n 就一直保存在内存中,那么,为什么会这样子呢,我们现在就来逐步地分析代码

    ① 首先 f1() 作为 f2() 的父函数,根据作用域链的规则, nAdd() 方法以及 f2() 方法中可以正常访问到 n 的值

    f2() 被赋予了一个全局变量,可能这里大家就会开始产生疑惑了,这个 f2() 不是好好地定义在了 f1() 函数中吗,这不是扯淡吗,那么,先看下面的这句 var result=f1(); ,这个 result 很明显是被赋予了一个全局变量,这应该是没有任何争议的,那么,接着来看这个 f1() ,可以看到最后,是一句 return f2; ,看到这里,想必大家也已经想明白了,这个 f2() 被赋予了一个全局变量

    ③ 已经明白了上面的这一点以后,根据上面垃圾回收机制所提及到的标记清除法,这个 f2() 始终是可以被根对象 Window 访问到的,所以 f2 将始终存在于内存之中,而 f2 是依赖于 f1 ,因此 f1 也将始终存在于内存当中,那么, n 的值也就自然始终存在于内存当中啦

    ④ 还有一点需要注意的就是为什么我们可以直接执行 nAdd() ,这是因为在 nAdd() 的前面没有使用 var ,因此 nAdd() 是一个全局函数而不是局部函数

    所以,闭包的变量会常驻内存,滥用闭包容易造成内存泄漏,特别是在 IE 浏览器下,2020年了,应该没人使用 IE 了吧(小声bb),解决办法就是在退出函数之前,将不使用的局部变量全部删除,这也是上面讲了垃圾回收机制 => 内存泄漏,再讲到闭包的原因,我会尽量将有关联性的知识点一起讲了,也方便大家学习和加深印象。

系列目录

相关免费学习推荐:javascript(视频)

The above is the detailed content of Understand the garbage collection mechanism, memory leaks, and closures of JS series (3) with one piece of paper. For more information, please follow other related articles on the PHP Chinese website!

Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn

Hot AI Tools

Undresser.AI Undress

Undresser.AI Undress

AI-powered app for creating realistic nude photos

AI Clothes Remover

AI Clothes Remover

Online AI tool for removing clothes from photos.

Undress AI Tool

Undress AI Tool

Undress images for free

Clothoff.io

Clothoff.io

AI clothes remover

AI Hentai Generator

AI Hentai Generator

Generate AI Hentai for free.

Hot Article

R.E.P.O. Energy Crystals Explained and What They Do (Yellow Crystal)
4 weeks ago By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. Best Graphic Settings
4 weeks ago By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. How to Fix Audio if You Can't Hear Anyone
1 months ago By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. Chat Commands and How to Use Them
1 months ago By 尊渡假赌尊渡假赌尊渡假赌

Hot Tools

Notepad++7.3.1

Notepad++7.3.1

Easy-to-use and free code editor

SublimeText3 Chinese version

SublimeText3 Chinese version

Chinese version, very easy to use

Zend Studio 13.0.1

Zend Studio 13.0.1

Powerful PHP integrated development environment

Dreamweaver CS6

Dreamweaver CS6

Visual web development tools

SublimeText3 Mac version

SublimeText3 Mac version

God-level code editing software (SublimeText3)

How to implement closure in C++ Lambda expression? How to implement closure in C++ Lambda expression? Jun 01, 2024 pm 05:50 PM

C++ Lambda expressions support closures, which save function scope variables and make them accessible to functions. The syntax is [capture-list](parameters)->return-type{function-body}. capture-list defines the variables to capture. You can use [=] to capture all local variables by value, [&] to capture all local variables by reference, or [variable1, variable2,...] to capture specific variables. Lambda expressions can only access captured variables but cannot modify the original value.

What are the advantages and disadvantages of closures in C++ functions? What are the advantages and disadvantages of closures in C++ functions? Apr 25, 2024 pm 01:33 PM

A closure is a nested function that can access variables in the scope of the outer function. Its advantages include data encapsulation, state retention, and flexibility. Disadvantages include memory consumption, performance impact, and debugging complexity. Additionally, closures can create anonymous functions and pass them to other functions as callbacks or arguments.

How to avoid memory leaks in Golang technical performance optimization? How to avoid memory leaks in Golang technical performance optimization? Jun 04, 2024 pm 12:27 PM

Memory leaks can cause Go program memory to continuously increase by: closing resources that are no longer in use, such as files, network connections, and database connections. Use weak references to prevent memory leaks and target objects for garbage collection when they are no longer strongly referenced. Using go coroutine, the coroutine stack memory will be automatically released when exiting to avoid memory leaks.

How to detect memory leaks using Valgrind? How to detect memory leaks using Valgrind? Jun 05, 2024 am 11:53 AM

Valgrind detects memory leaks and errors by simulating memory allocation and deallocation. To use it, follow these steps: Install Valgrind: Download and install the version for your operating system from the official website. Compile the program: Compile the program using Valgrind flags (such as gcc-g-omyprogrammyprogram.c-lstdc++). Analyze the program: Use the valgrind--leak-check=fullmyprogram command to analyze the compiled program. Check the output: Valgrind will generate a report after the program execution, showing memory leaks and error messages.

Debugging techniques for memory leaks in C++ Debugging techniques for memory leaks in C++ Jun 05, 2024 pm 10:19 PM

A memory leak in C++ means that the program allocates memory but forgets to release it, causing the memory to not be reused. Debugging techniques include using debuggers (such as Valgrind, GDB), inserting assertions, and using memory leak detector libraries (such as Boost.LeakDetector, MemorySanitizer). It demonstrates the use of Valgrind to detect memory leaks through practical cases, and proposes best practices to avoid memory leaks, including: always releasing allocated memory, using smart pointers, using memory management libraries, and performing regular memory checks.

How are closures implemented in Java? How are closures implemented in Java? May 03, 2024 pm 12:48 PM

Closures in Java allow inner functions to access outer scope variables even if the outer function has exited. Implemented through anonymous inner classes, the inner class holds a reference to the outer class and keeps the outer variables active. Closures increase code flexibility, but you need to be aware of the risk of memory leaks because references to external variables by anonymous inner classes keep those variables alive.

The role of golang function closure in testing The role of golang function closure in testing Apr 24, 2024 am 08:54 AM

Go language function closures play a vital role in unit testing: Capturing values: Closures can access variables in the outer scope, allowing test parameters to be captured and reused in nested functions. Simplify test code: By capturing values, closures simplify test code by eliminating the need to repeatedly set parameters for each loop. Improve readability: Use closures to organize test logic, making test code clearer and easier to read.

Summary of the advantages and disadvantages of golang anonymous functions and closures Summary of the advantages and disadvantages of golang anonymous functions and closures May 05, 2024 am 09:54 AM

Anonymous functions are concise and anonymous, but have poor readability and are difficult to debug; closures can encapsulate data and manage state, but may cause memory consumption and circular references. Practical case: Anonymous functions can be used for simple numerical processing, and closures can implement state management.

See all articles