awesome-interview/book2/browser-garbage.html

21 lines
21 KiB
HTML
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!doctype html>
<html lang="en" dir="ltr" class="docs-wrapper docs-doc-page docs-version-current plugin-docs plugin-id-default docs-doc-id-book2/browser-garbage">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<meta name="generator" content="Docusaurus v2.0.0-beta.18">
<link rel="search" type="application/opensearchdescription+xml" title="HZFE - 剑指前端 Offer" href="/awesome-interview/opensearch.xml">
<link rel="preconnect" href="https://hm.baidu.com">
<script>var _hmt=_hmt||[];!function(){var e=document.createElement("script");e.src="https://hm.baidu.com/hm.js?c7cd0fd77ac518cc6ef46461cdc9524b";var c=document.getElementsByTagName("script")[0];c.parentNode.insertBefore(e,c)}()</script>
<script src="https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js" async data-ad-client="ca-pub-9889934432771967"></script>
<script src="https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js?client=ca-pub-9889934432771967" async crossorigin="anonymous"></script><title data-rh="true">垃圾回收机制 | HZFE - 剑指前端 Offer</title><meta data-rh="true" name="twitter:card" content="summary_large_image"><meta data-rh="true" property="og:url" content="https://febook.hzfe.org/awesome-interview/book2/browser-garbage"><meta data-rh="true" name="docusaurus_locale" content="en"><meta data-rh="true" name="docsearch:language" content="en"><meta data-rh="true" name="docusaurus_version" content="current"><meta data-rh="true" name="docusaurus_tag" content="docs-default-current"><meta data-rh="true" name="docsearch:version" content="current"><meta data-rh="true" name="docsearch:docusaurus_tag" content="docs-default-current"><meta data-rh="true" property="og:title" content="垃圾回收机制 | HZFE - 剑指前端 Offer"><meta data-rh="true" name="description" content="相关问题"><meta data-rh="true" property="og:description" content="相关问题"><link data-rh="true" rel="icon" href="/awesome-interview/img/favicon.ico"><link data-rh="true" rel="canonical" href="https://febook.hzfe.org/awesome-interview/book2/browser-garbage"><link data-rh="true" rel="alternate" href="https://febook.hzfe.org/awesome-interview/book2/browser-garbage" hreflang="en"><link data-rh="true" rel="alternate" href="https://febook.hzfe.org/awesome-interview/book2/browser-garbage" hreflang="x-default"><link data-rh="true" rel="preconnect" href="https://PED5MQGL7T-dsn.algolia.net" crossorigin="anonymous"><link rel="stylesheet" href="/awesome-interview/assets/css/styles.62902d4b.css">
<link rel="preload" href="/awesome-interview/assets/js/runtime~main.16895322.js" as="script">
<link rel="preload" href="/awesome-interview/assets/js/main.a6349f88.js" as="script">
</head>
<body class="navigation-with-keyboard">
<script>!function(){function t(t){document.documentElement.setAttribute("data-theme",t)}var e=function(){var t=null;try{t=localStorage.getItem("theme")}catch(t){}return t}();t(null!==e?e:"light")}()</script><div id="__docusaurus">
<div role="region"><a href="#" class="skipToContent_ZgBM">Skip to main content</a></div><nav class="navbar navbar--fixed-top navbarHideable_ObN2"><div class="navbar__inner"><div class="navbar__items"><button aria-label="Navigation bar toggle" class="navbar__toggle clean-btn" type="button" tabindex="0"><svg width="30" height="30" viewBox="0 0 30 30" aria-hidden="true"><path stroke="currentColor" stroke-linecap="round" stroke-miterlimit="10" stroke-width="2" d="M4 7h22M4 15h22M4 23h22"></path></svg></button><a class="navbar__brand" href="/awesome-interview/"><div class="navbar__logo"><img src="/awesome-interview/img/badge.svg" alt="HZFE" class="themedImage_W2Cr themedImage--light_TfLj"><img src="/awesome-interview/img/badge.svg" alt="HZFE" class="themedImage_W2Cr themedImage--dark_oUvU"></div><b class="navbar__title">剑指前端 Offer</b></a></div><div class="navbar__items navbar__items--right"><a href="https://github.com/hzfe/awesome-interview" target="_blank" rel="noopener noreferrer" class="navbar__item navbar__link">GitHub<svg width="13.5" height="13.5" aria-hidden="true" viewBox="0 0 24 24" class="iconExternalLink_I5OW"><path fill="currentColor" d="M21 13v10h-21v-19h12v2h-10v15h17v-8h2zm3-12h-10.988l4.035 4-6.977 7.07 2.828 2.828 6.977-7.07 4.125 4.172v-11z"></path></svg></a><div class="searchBox_qEbK"><button type="button" class="DocSearch DocSearch-Button" aria-label="Search"><span class="DocSearch-Button-Container"><svg width="20" height="20" class="DocSearch-Search-Icon" viewBox="0 0 20 20"><path d="M14.386 14.386l4.0877 4.0877-4.0877-4.0877c-2.9418 2.9419-7.7115 2.9419-10.6533 0-2.9419-2.9418-2.9419-7.7115 0-10.6533 2.9418-2.9419 7.7115-2.9419 10.6533 0 2.9419 2.9418 2.9419 7.7115 0 10.6533z" stroke="currentColor" fill="none" fill-rule="evenodd" stroke-linecap="round" stroke-linejoin="round"></path></svg><span class="DocSearch-Button-Placeholder">Search</span></span><span class="DocSearch-Button-Keys"></span></button></div></div></div><div role="presentation" class="navbar-sidebar__backdrop"></div></nav><div class="main-wrapper"><div class="docPage_P2Lg"><button aria-label="Scroll back to top" class="clean-btn theme-back-to-top-button backToTopButton_RiI4" type="button"></button><aside class="theme-doc-sidebar-container docSidebarContainer_rKC_"><div class="sidebar_RiAD sidebarWithHideableNavbar_d0QC"><a tabindex="-1" class="sidebarLogo_YUvz" href="/awesome-interview/"><img src="/awesome-interview/img/badge.svg" alt="HZFE" class="themedImage_W2Cr themedImage--light_TfLj"><img src="/awesome-interview/img/badge.svg" alt="HZFE" class="themedImage_W2Cr themedImage--dark_oUvU"><b>剑指前端 Offer</b></a><nav class="menu thin-scrollbar menu_izAj"><ul class="theme-doc-sidebar-menu menu__list"><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-1 menu__list-item"><a class="menu__link" href="/awesome-interview/about">关于我们</a></li><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-1 menu__list-item"><a class="menu__link" href="/awesome-interview/">前言</a></li><li class="theme-doc-sidebar-item-category theme-doc-sidebar-item-category-level-1 menu__list-item menu__list-item--collapsed"><div class="menu__list-item-collapsible"><a class="menu__link menu__link--sublist menu__link--sublist-caret" aria-expanded="false" href="/awesome-interview/book1/browser-cross-origin">模拟题一</a></div></li><li class="theme-doc-sidebar-item-category theme-doc-sidebar-item-category-level-1 menu__list-item"><div class="menu__list-item-collapsible"><a class="menu__link menu__link--sublist menu__link--sublist-caret menu__link--active" aria-expanded="true" href="/awesome-interview/book2/browser-render-mechanism">模拟题二</a></div><ul style="display:block;overflow:visible;height:auto" class="menu__list"><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-2 menu__list-item"><a class="menu__link" tabindex="0" href="/awesome-interview/book2/browser-render-mechanism">浏览器:浏览器渲染机制</a></li><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-2 menu__list-item"><a class="menu__link menu__link--active" aria-current="page" tabindex="0" href="/awesome-interview/book2/browser-garbage">浏览器:垃圾回收机制</a></li><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-2 menu__list-item"><a class="menu__link" tabindex="0" href="/awesome-interview/book2/engineer-babel">工程化Babel 的原理</a></li><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-2 menu__list-item"><a class="menu__link" tabindex="0" href="/awesome-interview/book2/frame-react-fiber">框架React Fiber 的作用和原理</a></li><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-2 menu__list-item"><a class="menu__link" tabindex="0" href="/awesome-interview/book2/frame-react-hoc-hooks">框架HOC vs Render Props vs Hooks</a></li><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-2 menu__list-item"><a class="menu__link" tabindex="0" href="/awesome-interview/book2/js-inherite">基础ES5、ES6 如何实现继承</a></li><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-2 menu__list-item"><a class="menu__link" tabindex="0" href="/awesome-interview/book2/js-new">基础New 操作符的原理</a></li><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-2 menu__list-item"><a class="menu__link" tabindex="0" href="/awesome-interview/book2/css-preprocessor">样式:谈谈 CSS 预处理器</a></li><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-2 menu__list-item"><a class="menu__link" tabindex="0" href="/awesome-interview/book2/network-http-cache">网络HTTP 缓存机制</a></li><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-2 menu__list-item"><a class="menu__link" tabindex="0" href="/awesome-interview/book2/coding-throttle-debounce">编码:实现节流防抖函数</a></li><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-2 menu__list-item"><a class="menu__link" tabindex="0" href="/awesome-interview/book2/algorithm-reverse-linked-list">算法:反转链表</a></li><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-2 menu__list-item"><a class="menu__link" tabindex="0" href="/awesome-interview/book2/topic-multi-pics-site-optimize">综合:多图站点性能优化</a></li></ul></li><li class="theme-doc-sidebar-item-category theme-doc-sidebar-item-category-level-1 menu__list-item menu__list-item--collapsed"><div class="menu__list-item-collapsible"><a class="menu__link menu__link--sublist menu__link--sublist-caret" aria-expanded="false" href="/awesome-interview/book3/browser-event-loop">模拟题三</a></div></li><li class="theme-doc-sidebar-item-category theme-doc-sidebar-item-category-level-1 menu__list-item menu__list-item--collapsed"><div class="menu__list-item-collapsible"><a class="menu__link menu__link--sublist menu__link--sublist-caret" aria-expanded="false" href="/awesome-interview/book4/browser-router">模拟题四</a></div></li></ul></nav><button type="button" title="Collapse sidebar" aria-label="Collapse sidebar" class="button button--secondary button--outline collapseSidebarButton_FykI"><svg width="20" height="20" aria-hidden="true" class="collapseSidebarButtonIcon_DTRl"><g fill="#7a7a7a"><path d="M9.992 10.023c0 .2-.062.399-.172.547l-4.996 7.492a.982.982 0 01-.828.454H1c-.55 0-1-.453-1-1 0-.2.059-.403.168-.551l4.629-6.942L.168 3.078A.939.939 0 010 2.528c0-.548.45-.997 1-.997h2.996c.352 0 .649.18.828.45L9.82 9.472c.11.148.172.347.172.55zm0 0"></path><path d="M19.98 10.023c0 .2-.058.399-.168.547l-4.996 7.492a.987.987 0 01-.828.454h-3c-.547 0-.996-.453-.996-1 0-.2.059-.403.168-.551l4.625-6.942-4.625-6.945a.939.939 0 01-.168-.55 1 1 0 01.996-.997h3c.348 0 .649.18.828.45l4.996 7.492c.11.148.168.347.168.55zm0 0"></path></g></svg></button></div></aside><main class="docMainContainer_TCnq"><div class="container padding-top--md padding-bottom--lg"><div class="row"><div class="col docItemCol_DM6M"><div class="docItemContainer_vinB"><article><nav class="theme-doc-breadcrumbs breadcrumbsContainer_Xlws" aria-label="breadcrumbs"><ul class="breadcrumbs" itemscope="" itemtype="https://schema.org/BreadcrumbList"><li class="breadcrumbs__item"><a class="breadcrumbs__link" href="/awesome-interview/">🏠</a></li><li itemscope="" itemprop="itemListElement" itemtype="https://schema.org/ListItem" class="breadcrumbs__item"><span class="breadcrumbs__link" itemprop="item name">模拟题二</span><meta itemprop="position" content="1"></li><li itemscope="" itemprop="itemListElement" itemtype="https://schema.org/ListItem" class="breadcrumbs__item breadcrumbs__item--active"><span class="breadcrumbs__link" itemprop="item name">浏览器:垃圾回收机制</span><meta itemprop="position" content="2"></li></ul></nav><div class="tocCollapsible_jdIR theme-doc-toc-mobile tocMobile_TmEX"><button type="button" class="clean-btn tocCollapsibleButton_Fzxq">On this page</button></div><div class="theme-doc-markdown markdown"><h1>垃圾回收机制</h1><h2 class="anchor anchorWithHideOnScrollNavbar_R0VQ" id="相关问题">相关问题<a class="hash-link" href="#相关问题" title="Direct link to heading"></a></h2><ul><li>什么是内存泄漏</li><li>常见的垃圾回收算法</li><li>如何排查内存泄漏</li></ul><h2 class="anchor anchorWithHideOnScrollNavbar_R0VQ" id="回答关键点">回答关键点<a class="hash-link" href="#回答关键点" title="Direct link to heading"></a></h2><p><code>引用计数法</code> <code>标记清除法</code> <code>Mark-Compact标记整理</code> <code>Scavenger清道夫</code></p><p>GCGarbage Collection垃圾回收是一种内存自动管理机制 垃圾回收器Garbage Collector可以自动回收分配给程序的已经不再使用的内存。常见的 GC 算法有引用计数法和标记清除法等。V8JavaScript 引擎,提供执行 JavaScript 的运行时环境)的垃圾回收器算法主要由 Mark-Compact 和 Scavenger 构成。</p><h2 class="anchor anchorWithHideOnScrollNavbar_R0VQ" id="知识点深入">知识点深入<a class="hash-link" href="#知识点深入" title="Direct link to heading"></a></h2><h3 class="anchor anchorWithHideOnScrollNavbar_R0VQ" id="1-内存泄漏">1. 内存泄漏<a class="hash-link" href="#1-内存泄漏" title="Direct link to heading"></a></h3><p>内存泄漏是指,应当被回收的对象没有被正常回收,变成常驻老生代的对象,导致内存占用越来越高。内存泄漏会导致应用程序速度变慢、高延时、崩溃等问题。</p><h4 class="anchor anchorWithHideOnScrollNavbar_R0VQ" id="11-内存生命周期">1.1 内存生命周期<a class="hash-link" href="#11-内存生命周期" title="Direct link to heading"></a></h4><ol><li>分配:按需分配内存。</li><li>使用:读写已分配的内存。</li><li>释放:释放不再需要的内存。</li></ol><h4 class="anchor anchorWithHideOnScrollNavbar_R0VQ" id="12-内存泄漏常见原因">1.2 内存泄漏常见原因<a class="hash-link" href="#12-内存泄漏常见原因" title="Direct link to heading"></a></h4><ul><li>创建全局变量,且没有手动回收。</li><li>事件监听器 / 定时器 / 闭包等未正常清理。</li><li>使用 JavaScript 对象来做缓存,且不设置过期策略和对象大小控制。</li></ul><h3 class="anchor anchorWithHideOnScrollNavbar_R0VQ" id="2-reference-counting引用计数">2. Reference Counting引用计数<a class="hash-link" href="#2-reference-counting引用计数" title="Direct link to heading"></a></h3><p>Reference Counting 是常见的垃圾回收算法,其核心思路是:将资源(比如对象)的被引用次数保存起来,当被引用次数为零时释放。该方法的局限性:当出现<strong>循环引用</strong>时,互相引用的对象不会被回收。</p><h3 class="anchor anchorWithHideOnScrollNavbar_R0VQ" id="3-v8-垃圾回收机制">3. V8 垃圾回收机制<a class="hash-link" href="#3-v8-垃圾回收机制" title="Direct link to heading"></a></h3><p>V8 中有两个垃圾收集器。主要的 GC 使用 <strong>Mark-Compact</strong> 垃圾回收算法,从整个堆中收集垃圾。小型 GC 使用 <strong>Scavenger</strong> 垃圾回收算法,收集新生代垃圾。</p><p>两种不同的算法应对不同的场景:</p><ul><li>使用 Scavenger 算法主要处理<strong>存活周期短</strong>的对象中的可访问对象。</li><li>使用 Mark-Compact 算法主要处理<strong>存活周期长</strong>的对象中的不可访问的对象。</li></ul><p>因为新生代中存活的可访问对象占少数,老生代中的不可访问对象占少数,所以这两种回收算法配合使用十分高效。</p><h4 class="anchor anchorWithHideOnScrollNavbar_R0VQ" id="31-分代垃圾收集">3.1 分代垃圾收集<a class="hash-link" href="#31-分代垃圾收集" title="Direct link to heading"></a></h4><p>在 V8 中,所有的 JavaScript 对象都通过<strong></strong>来分配。V8 将其管理的堆分成两代新生代和老生代。其中新生代又可细分为两个子代Nursery、Intermediate</p><p>即新生代中的对象为存活时间较短的对象,老生代中的对象为存活时间较长或常驻内存的对象。</p><p><img loading="lazy" src="https://user-images.githubusercontent.com/17002181/126338733-69da76cd-33f3-4d0b-9a8e-c0e67ce0a331.png" alt="image" class="img_E7b_"></p><h4 class="anchor anchorWithHideOnScrollNavbar_R0VQ" id="32-mark-compact-算法major-gc">3.2 Mark-Compact 算法Major GC<a class="hash-link" href="#32-mark-compact-算法major-gc" title="Direct link to heading"></a></h4><p>Mark-Compact 算法可以看作是 Mark-Sweep标记清除算法和 Cheney 复制算法的结合。该算法主要分为三个阶段:标记、清除、整理。</p><p><img loading="lazy" src="https://user-images.githubusercontent.com/17002181/126341694-f3a454c4-4d88-4f7c-80b8-f323843eb6a3.png" alt="image" class="img_E7b_"></p><ol><li><p>标记Mark</p><p>标记是找所有可访问对象的过程。GC 会从一组已知的对象指针(称为根集,包括执行堆栈和全局对象等)中,进行递归标记可访问对象。</p></li><li><p>清除Sweep</p><p>清除是将不可访问的对象留下的内存空间添加到空闲链表free list的过程。未来为新对象分配内存时可以从空闲链表中进行再分配。</p></li><li><p>整理Compact</p><p>整理是将可访问对象,往内存一端移动的过程。主要解决标记清除阶段后,内存空间出现较多内存碎片时,可能导致无法分配大对象,而提前触发垃圾回收的问题。</p></li></ol><h4 class="anchor anchorWithHideOnScrollNavbar_R0VQ" id="33-scavenger-算法minor-gc">3.3 Scavenger 算法Minor GC<a class="hash-link" href="#33-scavenger-算法minor-gc" title="Direct link to heading"></a></h4><p>V8 对新生代内存空间采用了 Scavenger 算法,该算法使用了 semi-space半空间 的设计将堆一分为二始终只使用一半的空间From-Space 为使用空间To-Space 为空闲空间。</p><p><img loading="lazy" src="https://user-images.githubusercontent.com/17002181/126367817-b5a12c03-18ea-4eb9-8bdb-84d2fd3e8aad.png" alt="image" class="img_E7b_"></p><p>新生代在 From-Space 中分配对象;在垃圾回收阶段,检查并按需复制 From-Space 中的可访问对象到 To-Space 或老生代,并释放 From-Space 中的不可访问对象占用的内存空间;最后 From-Space 和 To-Space 角色互换。</p><h2 class="anchor anchorWithHideOnScrollNavbar_R0VQ" id="参考资料">参考资料<a class="hash-link" href="#参考资料" title="Direct link to heading"></a></h2><ol><li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Memory_Management" target="_blank" rel="noopener noreferrer">Memory Management</a></li><li><a href="https://v8.dev/blog/trash-talk" target="_blank" rel="noopener noreferrer">Trash talk: the Orinoco garbage collector</a></li></ol></div></article><nav class="pagination-nav docusaurus-mt-lg" aria-label="Docs pages navigation"><div class="pagination-nav__item"><a class="pagination-nav__link" href="/awesome-interview/book2/browser-render-mechanism"><div class="pagination-nav__sublabel">Previous</div><div class="pagination-nav__label">浏览器:浏览器渲染机制</div></a></div><div class="pagination-nav__item pagination-nav__item--next"><a class="pagination-nav__link" href="/awesome-interview/book2/engineer-babel"><div class="pagination-nav__sublabel">Next</div><div class="pagination-nav__label">工程化Babel 的原理</div></a></div></nav></div></div><div class="col col--3"><div class="tableOfContents_cNA8 thin-scrollbar theme-doc-toc-desktop"><ul class="table-of-contents table-of-contents__left-border"><li><a href="#相关问题" class="table-of-contents__link toc-highlight">相关问题</a></li><li><a href="#回答关键点" class="table-of-contents__link toc-highlight">回答关键点</a></li><li><a href="#知识点深入" class="table-of-contents__link toc-highlight">知识点深入</a><ul><li><a href="#1-内存泄漏" class="table-of-contents__link toc-highlight">1. 内存泄漏</a><ul><li><a href="#11-内存生命周期" class="table-of-contents__link toc-highlight">1.1 内存生命周期</a></li><li><a href="#12-内存泄漏常见原因" class="table-of-contents__link toc-highlight">1.2 内存泄漏常见原因</a></li></ul></li><li><a href="#2-reference-counting引用计数" class="table-of-contents__link toc-highlight">2. Reference Counting引用计数</a></li><li><a href="#3-v8-垃圾回收机制" class="table-of-contents__link toc-highlight">3. V8 垃圾回收机制</a><ul><li><a href="#31-分代垃圾收集" class="table-of-contents__link toc-highlight">3.1 分代垃圾收集</a></li><li><a href="#32-mark-compact-算法major-gc" class="table-of-contents__link toc-highlight">3.2 Mark-Compact 算法Major GC</a></li><li><a href="#33-scavenger-算法minor-gc" class="table-of-contents__link toc-highlight">3.3 Scavenger 算法Minor GC</a></li></ul></li></ul></li><li><a href="#参考资料" class="table-of-contents__link toc-highlight">参考资料</a></li></ul></div></div></div><div class="row"><div class="col"><div class="react-utterences"><div>Loading script...</div></div></div><div class="col col--3"></div></div></div></main></div></div></div>
<script src="/awesome-interview/assets/js/runtime~main.16895322.js"></script>
<script src="/awesome-interview/assets/js/main.a6349f88.js"></script>
</body>
</html>