<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>垃圾回收 on Last Stand</title><link>https://amatsuzero.github.io/LastStand/tags/%E5%9E%83%E5%9C%BE%E5%9B%9E%E6%94%B6/</link><description>Recent content in 垃圾回收 on Last Stand</description><generator>Hugo</generator><language>zh-cn</language><lastBuildDate>Tue, 24 Dec 2024 00:00:00 +0800</lastBuildDate><atom:link href="https://amatsuzero.github.io/LastStand/tags/%E5%9E%83%E5%9C%BE%E5%9B%9E%E6%94%B6/index.xml" rel="self" type="application/rss+xml"/><item><title>垃圾回收</title><link>https://amatsuzero.github.io/LastStand/posts/frontend/javascript/javascript-016/</link><pubDate>Tue, 01 Oct 2024 00:00:00 +0800</pubDate><guid>https://amatsuzero.github.io/LastStand/posts/frontend/javascript/javascript-016/</guid><description>&lt;h2 id="写在前面"&gt;写在前面&lt;/h2&gt;
&lt;p&gt;我们知道垃圾回收机制是引擎来做的，JS引擎有很多种（各个浏览器都不同），其垃圾回收机制在一些细节及优化上略有不同，本文我们以一些通用的回收算法作为切入，再由 V8 引擎发展至今对该机制的优化为例（为什么以 V8 为例？因为它市场占有率大 😄 ），一步一步深入来助我们了解垃圾回收机制，因为只有真正了解垃圾回收机制，后面才能理解内存泄漏的问题以及手动预防和优化&lt;/p&gt;
&lt;p&gt;JavaScript 是门魅力无限的语言，关于它的 GC（垃圾回收）方面，你了解多少呢？想来大部分人是因为面试才去看一些面试题从而了解的垃圾回收，那在正式开始之前，给大家列几个小问题，大家可以先想一下答案，带着问题及答案再去看文章，最后读完此文如果你的答案可以优化，即有收获&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;什么是垃圾回收机制？&lt;/li&gt;
&lt;li&gt;垃圾是怎样产生的？&lt;/li&gt;
&lt;li&gt;为什么要进行垃圾回收？&lt;/li&gt;
&lt;li&gt;垃圾回收是怎样进行的？&lt;/li&gt;
&lt;li&gt;V8 引擎对垃圾回收进行了哪些优化？&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;当然，我们可不仅仅是为了面试，其目的是一次性彻底搞懂 GC！&lt;/p&gt;
&lt;h2 id="gc是什么"&gt;GC是什么&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;GC&lt;/code&gt; 即 &lt;code&gt;Garbage Collection&lt;/code&gt; ，程序工作过程中会产生很多 &lt;code&gt;垃圾&lt;/code&gt;，这些垃圾是程序不用的内存或者是之前用过了，以后不会再用的内存空间，而 &lt;code&gt;GC&lt;/code&gt; 就是负责回收垃圾的，因为他工作在引擎内部，所以对于我们前端来说，&lt;code&gt;GC&lt;/code&gt; 过程是相对比较无感的，这一套引擎执行而对我们又相对无感的操作也就是常说的 &lt;code&gt;垃圾回收机制&lt;/code&gt; 了&lt;/p&gt;
&lt;p&gt;当然也不是所有语言都有 &lt;code&gt;GC&lt;/code&gt;，一般的高级语言里面会自带 &lt;code&gt;GC&lt;/code&gt;，比如 &lt;code&gt;Java、Python、JavaScript&lt;/code&gt; 等，也有无 &lt;code&gt;GC&lt;/code&gt; 的语言，比如 &lt;code&gt;C、C++&lt;/code&gt; 等，那这种就需要我们程序员手动管理内存了，相对比较麻烦&lt;/p&gt;
&lt;h2 id="垃圾产生为何回收"&gt;垃圾产生&amp;amp;为何回收&lt;/h2&gt;
&lt;p&gt;我们知道写代码时创建一个基本类型、对象、函数……都是需要占用内存的，但是我们并不关注这些，因为这是引擎为我们分配的，我们不需要显式手动的去分配内存&lt;/p&gt;
&lt;p&gt;但是，你有没有想过，当我们不再需要某个东西时会发生什么？JavaScript 引擎又是如何发现并清理它的呢？&lt;/p&gt;
&lt;p&gt;我们举个简单的例子&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-js" data-lang="js"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;let&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;test&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;name&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;isboyjc&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;};
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;test&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; [&lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;,&lt;span style="color:#ae81ff"&gt;2&lt;/span&gt;,&lt;span style="color:#ae81ff"&gt;3&lt;/span&gt;,&lt;span style="color:#ae81ff"&gt;4&lt;/span&gt;,&lt;span style="color:#ae81ff"&gt;5&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;如上所示，我们假设它是一个完整的程序代码&lt;/p&gt;
&lt;p&gt;我们知道 &lt;code&gt;JavaScript&lt;/code&gt; 的引用数据类型是保存在堆内存中的，然后在栈内存中保存一个对堆内存中实际对象的引用，所以，&lt;code&gt;JavaScript&lt;/code&gt; 中对引用数据类型的操作都是操作对象的引用而不是实际的对象。可以简单理解为，栈内存中保存了一个地址，这个地址和堆内存中的实际值是相关的&lt;/p&gt;
&lt;p&gt;那上面代码首先我们声明了一个变量 &lt;code&gt;test&lt;/code&gt;，它引用了对象 &lt;code&gt;{name: 'isboyjc'}&lt;/code&gt;，接着我们把这个变量重新赋值了一个数组对象，也就变成了该变量引用了一个数组，那么之前的对象引用关系就没有了，如下图&lt;/p&gt;
&lt;p&gt;&lt;img loading="lazy" src="https://amatsuzero.github.io/LastStand/posts/frontend/javascript/javascript-016/image-01.webp"&gt;&lt;/p&gt;
&lt;p&gt;没有了引用关系，也就是无用的对象，这个时候假如任由它搁置，一个两个还好，多了的话内存也会受不了，所以就需要被清理（回收）&lt;/p&gt;
&lt;p&gt;用官方一点的话说，程序的运行需要内存，只要程序提出要求，操作系统或者运行时就必须提供内存，那么对于持续运行的服务进程，必须要及时释放内存，否则，内存占用越来越高，轻则影响系统性能，重则就会导致进程崩溃&lt;/p&gt;
&lt;h2 id="垃圾回收策略"&gt;垃圾回收策略&lt;/h2&gt;
&lt;p&gt;在 JavaScript 内存管理中有一个概念叫做 &lt;code&gt;可达性&lt;/code&gt;，就是那些以某种方式可访问或者说可用的值，它们被保证存储在内存中，反之不可访问则需回收&lt;/p&gt;
&lt;p&gt;至于如何回收，其实就是怎样发现这些不可达的对象（垃圾）它并给予清理的问题， &lt;code&gt;JavaScript&lt;/code&gt; 垃圾回收机制的原理说白了也就是定期找出那些不再用到的内存（变量），然后释放其内存&lt;/p&gt;</description></item></channel></rss>