awesome-interview/book2/browser-garbage.html

19 lines
18 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters

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">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<meta name="generator" content="Docusaurus v2.0.0-beta.5">
<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><title data-react-helmet="true">垃圾回收机制 | HZFE - 剑指前端 Offer</title><meta data-react-helmet="true" name="twitter:card" content="summary_large_image"><meta data-react-helmet="true" property="og:url" content="https://febook.hzfe.org/awesome-interview/book2/browser-garbage"><meta data-react-helmet="true" name="docsearch:language" content="en"><meta data-react-helmet="true" name="docsearch:version" content="current"><meta data-react-helmet="true" name="docsearch:docusaurus_tag" content="docs-default-current"><meta data-react-helmet="true" property="og:title" content="垃圾回收机制 | HZFE - 剑指前端 Offer"><meta data-react-helmet="true" name="description" content="相关问题"><meta data-react-helmet="true" property="og:description" content="相关问题"><link data-react-helmet="true" rel="shortcut icon" href="/awesome-interview/img/favicon.ico"><link data-react-helmet="true" rel="canonical" href="https://febook.hzfe.org/awesome-interview/book2/browser-garbage"><link data-react-helmet="true" rel="alternate" href="https://febook.hzfe.org/awesome-interview/book2/browser-garbage" hreflang="en"><link data-react-helmet="true" rel="alternate" href="https://febook.hzfe.org/awesome-interview/book2/browser-garbage" hreflang="x-default"><link data-react-helmet="true" rel="preconnect" href="https://BH4D9OD16A-dsn.algolia.net" crossorigin="anonymous"><link rel="stylesheet" href="/awesome-interview/assets/css/styles.304d13b7.css">
<link rel="preload" href="/awesome-interview/assets/js/runtime~main.e4536af0.js" as="script">
<link rel="preload" href="/awesome-interview/assets/js/main.52f9823f.js" as="script">
</head>
<body>
<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><a href="#" class="skipToContent_1oUP">Skip to main content</a></div><nav class="navbar navbar--fixed-top navbarHideable_2qcr"><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/"><img src="/awesome-interview/img/badge.svg" alt="HZFE" class="themedImage_1VuW themedImage--light_3UqQ navbar__logo"><img src="/awesome-interview/img/badge.svg" alt="HZFE" class="themedImage_1VuW themedImage--dark_hz6m navbar__logo"><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"><span>GitHub<svg width="13.5" height="13.5" aria-hidden="true" viewBox="0 0 24 24" class="iconExternalLink_3J9K"><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></span></a><div class="searchBox_1Doo"><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 docs-wrapper docs-doc-page"><div class="docPage_31aa"><button class="clean-btn backToTopButton_35hR" type="button"><svg viewBox="0 0 24 24" width="28"><path d="M7.41 15.41L12 10.83l4.59 4.58L18 14l-6-6-6 6z" fill="currentColor"></path></svg></button><aside class="docSidebarContainer_3Kbt"><div class="sidebar_15mo sidebarWithHideableNavbar_267A"><a tabindex="-1" class="sidebarLogo_3h0W" href="/awesome-interview/"><img src="/awesome-interview/img/badge.svg" alt="HZFE" class="themedImage_1VuW themedImage--light_3UqQ"><img src="/awesome-interview/img/badge.svg" alt="HZFE" class="themedImage_1VuW themedImage--dark_hz6m"><b>剑指前端 Offer</b></a><nav class="menu thin-scrollbar menu_Bmed menuWithAnnouncementBar_2WvA"><ul class="menu__list"><li class="menu__list-item"><a class="menu__link" href="/awesome-interview/about">关于我们</a></li><li class="menu__list-item"><a class="menu__link" href="/awesome-interview/">前言</a></li><li class="menu__list-item menu__list-item--collapsed"><a class="menu__link menu__link--sublist" href="#">模拟题一</a></li><li class="menu__list-item"><a class="menu__link menu__link--sublist menu__link--active" href="#">模拟题二</a><ul style="display:block;overflow:visible;height:auto" class="menu__list"><li class="menu__list-item"><a class="menu__link" tabindex="0" href="/awesome-interview/book2/browser-render-mechanism">浏览器:浏览器渲染机制</a></li><li class="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="menu__list-item"><a class="menu__link" tabindex="0" href="/awesome-interview/book2/engineer-babel">工程化Babel 的原理</a></li><li class="menu__list-item"><a class="menu__link" tabindex="0" href="/awesome-interview/book2/frame-react-fiber">框架React Fiber 的作用和原理</a></li><li class="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="menu__list-item"><a class="menu__link" tabindex="0" href="/awesome-interview/book2/js-inherite">基础ES5、ES6 如何实现继承</a></li><li class="menu__list-item"><a class="menu__link" tabindex="0" href="/awesome-interview/book2/js-new">基础New 操作符的原理</a></li><li class="menu__list-item"><a class="menu__link" tabindex="0" href="/awesome-interview/book2/css-preprocessor">样式:谈谈 CSS 预处理器</a></li><li class="menu__list-item"><a class="menu__link" tabindex="0" href="/awesome-interview/book2/network-http-cache">网络HTTP 缓存机制</a></li><li class="menu__list-item"><a class="menu__link" tabindex="0" href="/awesome-interview/book2/coding-throttle-debounce">编码:实现节流去抖函数</a></li><li class="menu__list-item"><a class="menu__link" tabindex="0" href="/awesome-interview/book2/algorithm-reverse-linked-list">算法:反转链表</a></li><li class="menu__list-item"><a class="menu__link" tabindex="0" href="/awesome-interview/book2/topic-multi-pics-site-optimize">综合:多图站点性能优化</a></li></ul></li><li class="menu__list-item menu__list-item--collapsed"><a class="menu__link menu__link--sublist" href="#">模拟题三</a></li></ul></nav><button type="button" title="Collapse sidebar" aria-label="Collapse sidebar" class="button button--secondary button--outline collapseSidebarButton_1CGd"><svg width="20" height="20" aria-hidden="true" class="collapseSidebarButtonIcon_3E-R"><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_3ufF"><div class="container padding-top--md padding-bottom--lg"><div class="row"><div class="col docItemCol_3FnS"><div class="docItemContainer_33ec"><article><div class="tocCollapsible_1PrD tocMobile_3Hoh"><button type="button" class="clean-btn tocCollapsibleButton_2O1e">On this page</button></div><div class="markdown"><header><h1>垃圾回收机制</h1></header><h2><a aria-hidden="true" tabindex="-1" class="anchor anchor__h2 anchorWithHideOnScrollNavbar_3R7-" id="相关问题"></a>相关问题<a class="hash-link" href="#相关问题" title="Direct link to heading">#</a></h2><ul><li>什么是内存泄漏</li><li>常见的垃圾回收算法</li><li>如何排查内存泄漏</li></ul><h2><a aria-hidden="true" tabindex="-1" class="anchor anchor__h2 anchorWithHideOnScrollNavbar_3R7-" id="回答关键点"></a>回答关键点<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><a aria-hidden="true" tabindex="-1" class="anchor anchor__h2 anchorWithHideOnScrollNavbar_3R7-" id="知识点深入"></a>知识点深入<a class="hash-link" href="#知识点深入" title="Direct link to heading">#</a></h2><h3><a aria-hidden="true" tabindex="-1" class="anchor anchor__h3 anchorWithHideOnScrollNavbar_3R7-" id="1-内存泄漏"></a>1. 内存泄漏<a class="hash-link" href="#1-内存泄漏" title="Direct link to heading">#</a></h3><p>内存泄漏是指,应当被回收的对象没有被正常回收,变成常驻老生代的对象,导致内存占用越来越高。内存泄漏会导致应用程序速度变慢、高延时、崩溃等问题。</p><h4><a aria-hidden="true" tabindex="-1" class="anchor anchor__h4 anchorWithHideOnScrollNavbar_3R7-" id="11-内存生命周期"></a>1.1 内存生命周期<a class="hash-link" href="#11-内存生命周期" title="Direct link to heading">#</a></h4><ol><li>分配:按需分配内存。</li><li>使用:读写已分配的内存。</li><li>释放:释放不再需要的内存。</li></ol><h4><a aria-hidden="true" tabindex="-1" class="anchor anchor__h4 anchorWithHideOnScrollNavbar_3R7-" id="12-内存泄漏常见原因"></a>1.2 内存泄漏常见原因<a class="hash-link" href="#12-内存泄漏常见原因" title="Direct link to heading">#</a></h4><ul><li>创建全局变量,且没有手动回收。</li><li>事件监听器 / 定时器 / 闭包等未正常清理。</li><li>使用 JavaScript 对象来做缓存,且不设置过期策略和对象大小控制。</li><li>队列拥塞所带来的消费不及时问题。</li></ul><h3><a aria-hidden="true" tabindex="-1" class="anchor anchor__h3 anchorWithHideOnScrollNavbar_3R7-" id="2-reference-counting引用计数"></a>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><a aria-hidden="true" tabindex="-1" class="anchor anchor__h3 anchorWithHideOnScrollNavbar_3R7-" id="3-v8-垃圾回收机制"></a>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><a aria-hidden="true" tabindex="-1" class="anchor anchor__h4 anchorWithHideOnScrollNavbar_3R7-" id="31-分代垃圾收集"></a>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 src="https://user-images.githubusercontent.com/17002181/126338733-69da76cd-33f3-4d0b-9a8e-c0e67ce0a331.png" alt="image"></p><h4><a aria-hidden="true" tabindex="-1" class="anchor anchor__h4 anchorWithHideOnScrollNavbar_3R7-" id="32-mark-compact-算法major-gc"></a>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 src="https://user-images.githubusercontent.com/17002181/126341694-f3a454c4-4d88-4f7c-80b8-f323843eb6a3.png" alt="image"></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><a aria-hidden="true" tabindex="-1" class="anchor anchor__h4 anchorWithHideOnScrollNavbar_3R7-" id="33-scavenger-算法minor-gc"></a>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 src="https://user-images.githubusercontent.com/17002181/126367817-b5a12c03-18ea-4eb9-8bdb-84d2fd3e8aad.png" alt="image"></p><p>新生代在 From-Space 中分配对象;在垃圾回收阶段,检查并按需复制 From-Space 中的可访问对象到 To-Space 或老生代,并释放 From-Space 中的不可访问对象占用的内存空间;最后 From-Space 和 To-Space 角色互换。</p><h2><a aria-hidden="true" tabindex="-1" class="anchor anchor__h2 anchorWithHideOnScrollNavbar_3R7-" id="参考资料"></a>参考资料<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_35-E thin-scrollbar"><ul class="table-of-contents table-of-contents__left-border"><li><a href="#相关问题" class="table-of-contents__link">相关问题</a></li><li><a href="#回答关键点" class="table-of-contents__link">回答关键点</a></li><li><a href="#知识点深入" class="table-of-contents__link">知识点深入</a><ul><li><a href="#1-内存泄漏" class="table-of-contents__link">1. 内存泄漏</a></li><li><a href="#2-reference-counting引用计数" class="table-of-contents__link">2. Reference Counting引用计数</a></li><li><a href="#3-v8-垃圾回收机制" class="table-of-contents__link">3. V8 垃圾回收机制</a></li></ul></li><li><a href="#参考资料" class="table-of-contents__link">参考资料</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.e4536af0.js"></script>
<script src="/awesome-interview/assets/js/main.52f9823f.js"></script>
</body>
</html>