JavaScriptにはGCがあるのでしょうか?
JavaScriptにはGC(ガベージコレクション機構)というものがあります。 JavaScript はガベージ コレクション機構を使用する言語であり、コード実行時に実行環境がメモリを管理し、ガベージ オブジェクト (参照されていないオブジェクト) をメモリから自動的に破棄します。
このチュートリアルの動作環境: Windows7 システム、JavaScript バージョン 1.8.5、Dell G3 コンピューター。
JavaScript のガベージ コレクション メカニズム (GC)
ガベージ コレクション関連の概念
① とははガベージです
使用されていない (参照されていない) オブジェクトは ガベージです。
② ガベージ コレクションとは
参照されていないオブジェクトを破棄してメモリを解放する、これが ガベージ コレクションです。
C や C などのプログラミング言語では、手動のガベージ コレクションが必要です。
Java、JavaScript、PHP、Python、その他の言語の自動ガベージ コレクション。
JS には自動ガベージ コレクション メカニズムがあり、これらのガベージ オブジェクトをメモリから自動的に破棄します。ガベージ コレクション操作は必要なく、実行することもできません。必要なのは、使用されなくなったオブジェクトを null に設定することだけです。
ガベージ コレクションが必要な理由
- C/C では、メモリ使用量の追跡とメモリ管理は開発者にとって大きな負担です
- JavaScript は、ガベージ コレクション メカニズム。これは、コードの実行時に実行環境がメモリを管理する責任を負い、開発者がこの負担を軽減できるようにすることを意味します。
- 自動メモリ管理を通じてメモリ割り当てとリソースのリサイクルを実現します
- 基本的な考え方は非常に単純です。どの変数が使用されなくなるかを判断し、そのメモリ領域を解放します。
- このプロセスは周期的です。つまり、ガベージ コレクション プログラムが時々実行されることになります。
- JS のオブジェクト、文字列、およびオブジェクトのメモリは固定されていません。メモリは実際に使用されるときにのみ動的に割り当てられます。
- これらのメモリは、後で解放する必要があります。再使用できるように使用中です。そうしないと、コンピュータの使用可能なメモリが使い果たされた後にクラッシュが発生します。
- ブラウザ開発の歴史における主なガベージ コレクション メソッドは、
- です。
- リファレンスカウント方法
- マーククリア方法
リファレンスカウント方法
アイデア
- 変数は値のみを参照します
- 変数が値を参照する場合、参照数は 1
- 変数への参照が上書きまたはクリアされた場合、参照数 -1
- 参照数が 0 の場合、このメモリは安全に解放できます。
let arr = [1, 0, 1] // [1, 0, 1]这块内存被arr引用 引用次数为1 arr = [0, 1, 0] // [1, 0, 1]的内存引用次数为0被释放 // [0, 1, 0]的内存被arr引用 引用次数为1 const tmp = arr // [0, 1, 0]的内存被tmp引用 引用次数为2
循環参照の問題
Netscape Navigator 3.0 は
- を採用この例では、ObjectA と ObjectB のプロパティがそれぞれ相互参照しています。
- その結果、この関数実行後、Object の参照回数が 0 にならず、通常の GC に影響を及ぼします。
- 複数回実行すると、重大なメモリ リークが発生します。
- マークアンドクリア方式ではこの問題は発生しません。
function Example(){ let ObjectA = new Object(); let ObjectB = new Object(); ObjectA.p = ObjectB; ObjectB.p = ObjectA; } Example();
- 解決策: 関数の最後で null を指すようにします
ObjectA = null; ObjectB = null;
マーククリアメソッド
##循環参照によって引き起こされるメモリ リークの問題を解決するために、Netscape Navigator 4.0 はマーク アンド クリア メソッドを使用し始めました。
2008 年までに、IE、 Firefox、Opera、Chrome、Safari はどちらも JavaScript 実装でマークアップ クリーニング (またはその亜種) を使用しており、ガベージ コレクションを実行する頻度のみが異なります。
アイデア
- 変数が実行コンテキストに入るときに「エントリ」マークをマークします
- 同時に、変数が実行コンテキストから離れるとき "leave" をマークします。
- 今後、この変数にアクセスできなくなります
- 次回のガベージ コレクション中にメモリが解放されます
function Example(n){ const a = 1, b = 2, c = 3; return n * a * b * c; } // 标记Example进入执行上下文 const n = 1; // 标记n进入执行上下文 Example(n); // 标记a,b,c进入执行上下文 console.log(n); // 标记a, b, c离开执行上下文,等待垃圾回收
const と let ステートメントでパフォーマンスを向上させる
- const と let は、コード スタイルの改善だけでなく、ガベージ コレクションのパフォーマンスの改善にも役立ちます
- const で JS を作成する ブロック レベル スコープでは、ブロック レベル スコープが関数スコープよりも早く終了する場合、ガベージ コレクション プログラムがより早く介入します。
- 回復されたメモリをできるだけ早くリサイクルして、メモリを改善します。ガベージ コレクションのパフォーマンス
V8 エンジンのガベージ コレクション
#V8 エンジンのガベージ コレクションには、マークアンドスイープ方式と世代別収集方式
新世代と旧世代に分かれる
新世代
##新世代ガベージ コレクションはScavenge共有メモリと新たに割り当てられた少量のメモリに割り当てアルゴリズムを採用
- メモリ サイズ
- 32 ビット システム 16M メモリ
- 64 ビット システム 32M メモリ
新世代メモリは次の 2 つの領域に分割され、メモリの半分
- From spaceTo space
実際に実行するのはスペースからのみです
- スペースへはアイドル状態です
- 当From space内存使用将要达到上限时开始垃圾回收,将From space中的不可达对象都打上标记
- 将From space的未标记对象复制到To space。
- 解决了内存散落分块的问题(不连续的内存空间)
- 相当于用空间换时间。
- 然后清空From space、将其闲置,也就是转变为To space,俗称反转。
新生代 -> 老生代
- 新生代存放的是新分配的小量内存,如果达到以下条件中的一个,将被分配至老生代
- 内存大小达到From space的25%
- 经历了From space <-> To space的一个轮回
- 新生代存放的是新分配的小量内存,如果达到以下条件中的一个,将被分配至老生代
老生代
老生代采用
mark-sweep
标记清除和mark-compact
标记整理
通常存放较大的内存块和从新生代分配过来的内存块
- 内存大小
- 32位系统700M左右
- 64位系统1.4G左右
- 分区
- Old Object Space
- 字面的老生代,存放的是新生代分配过来的内存。
- Large Object Space
- 存放其他区域放不下的较大的内存,基本都超过1M
- Map Space
- 存放存储对象的映射关系
- Code Space
- 存储编译后的代码
- Old Object Space
- 回收流程
- 标记分类(三色标记)
- 未被扫描,可回收,下面简称
1类
- 扫描中,不可回收,下面简称
2类
- 扫描完成,不可回收,下面简称
3类
- 未被扫描,可回收,下面简称
- 遍历
- 采用深度优先遍历,遍历每个对象。
- 首先将非根部对象全部标记为
1类
,然后进行深度优先遍历。 - 遍历过程中将对象压入栈,这个过程中对象被标记为
2类
。 - 遍历完成对象出栈,这个对象被标记为
3类
。 - 整个过程直至栈空
- Mark-sweep
标记完成之后,将标记为
1类
的对象进行内存释放
- 标记分类(三色标记)
Mark-compact
垃圾回收完成之后,内存空间是不连续的。
这样容易造成无法分配较大的内存空间的问题,从而触发垃圾回收。
所以,会有Mark-compact步骤将未被回收的内存块整理为连续地内存空间。
频繁触发垃圾回收会影响引擎的性能,内存空间不足时也会优先触发Mark-compact
垃圾回收优化
- 增量标记
- 如果用集中的一段时间进行垃圾回收,新生代倒还好,老生代如果遍历较大的对象,可能会造成卡顿。
- 增量标记:使垃圾回收程序和应用逻辑程序交替运行,思想类似Time Slicing
- 并行回收
- 在垃圾回收的过程中,开启若干辅助线程,提高垃圾回收效率。
- 并发回收
- 在逻辑程序执行的过程中,开启若干辅助线程进行垃圾回收,清理和主线程没有任何逻辑关系的内存。
内存泄露场景
全局变量
// exm1 function Example(){ exm = 'LeBron' } // exm2 function Example(){ this.exm = 'LeBron' } Example()
未清除的定时器
const timer = setInterval(() => { //... }, 1000) // clearInterval(timer)
闭包
function debounce(fn, time) { let timeout = null; return function () { if (timeout) { clearTimeout(timeout); } timeout = setTimeout(() => { fn.apply(this, arguments); }, time); }; } const fn = debounce(handler, 1000); // fn引用了timeout
未清除的DOM元素引用
const element = { // 此处引用了DOM元素 button:document.getElementById('LeBron'), select:document.getElementById('select') } document.body.removeChild(document.getElementById('LeBron'))
如何检测内存泄漏
这个其实不难,浏览器原带的开发者工具Performance就可以
- 步骤
- F12打开开发者工具
- 选择Performance工具栏
- 勾选屏幕截图和Memory
- 点击开始录制
- 一段时间之后结束录制
- 结果
- 堆内存会周期性地分配和释放
- 如果堆内存的min值在逐渐上升则存在内存泄漏
优化内存使用
1、尽量不在for循环中定义函数
// exm const fn = (idx) => { return idx * 2; } function Example(){ for(let i=0;i<1000;i++){ //const fn = (idx) => { // return idx * 2; // } const res = fn(i); } }
2、尽量不在for循环中定义对象
function Example() { const obj = {}; let res = ""; for (let i = 0; i < 1000; i++) { // const obj = { // a: i, // b: i * 2, // c: i * 3, // }; obj.a = i; obj.b = i * 2; obj.c = i * 3; res += JSON.stringify(obj); } return res }
3、清空数组
arr = [0, 1, 2] arr.length = 0; // 清空了数组,数组类型不变 // arr = [] // 重新申请了一块空数组对象内存
【推荐学习:javascript高级教程】
以上がJavaScriptにはGCがあるのでしょうか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

ホットAIツール

Undresser.AI Undress
リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover
写真から衣服を削除するオンライン AI ツール。

Undress AI Tool
脱衣画像を無料で

Clothoff.io
AI衣類リムーバー

AI Hentai Generator
AIヘンタイを無料で生成します。

人気の記事

ホットツール

メモ帳++7.3.1
使いやすく無料のコードエディター

SublimeText3 中国語版
中国語版、とても使いやすい

ゼンドスタジオ 13.0.1
強力な PHP 統合開発環境

ドリームウィーバー CS6
ビジュアル Web 開発ツール

SublimeText3 Mac版
神レベルのコード編集ソフト(SublimeText3)

ホットトピック











WebSocket と JavaScript を使用してオンライン音声認識システムを実装する方法 はじめに: 技術の継続的な発展により、音声認識技術は人工知能の分野の重要な部分になりました。 WebSocket と JavaScript をベースとしたオンライン音声認識システムは、低遅延、リアルタイム、クロスプラットフォームという特徴があり、広く使用されるソリューションとなっています。この記事では、WebSocket と JavaScript を使用してオンライン音声認識システムを実装する方法を紹介します。

WebSocketとJavaScript:リアルタイム監視システムを実現するためのキーテクノロジー はじめに: インターネット技術の急速な発展に伴い、リアルタイム監視システムは様々な分野で広く利用されています。リアルタイム監視を実現するための重要なテクノロジーの 1 つは、WebSocket と JavaScript の組み合わせです。この記事では、リアルタイム監視システムにおける WebSocket と JavaScript のアプリケーションを紹介し、コード例を示し、その実装原理を詳しく説明します。 1.WebSocketテクノロジー

WebSocket と JavaScript を使用してオンライン予約システムを実装する方法 今日のデジタル時代では、ますます多くの企業やサービスがオンライン予約機能を提供する必要があります。効率的かつリアルタイムのオンライン予約システムを実装することが重要です。この記事では、WebSocket と JavaScript を使用してオンライン予約システムを実装する方法と、具体的なコード例を紹介します。 1. WebSocket とは何ですか? WebSocket は、単一の TCP 接続における全二重方式です。

Golang のガベージ コレクション (GC) は、開発者の間で常に話題になっています。高速プログラミング言語として、Golang の組み込みガベージ コレクターはメモリを適切に管理できますが、プログラムのサイズが大きくなるにつれて、パフォーマンスの問題が発生することがあります。この記事では、Golang の GC 最適化戦略を検討し、いくつかの具体的なコード例を示します。 Golang のガベージ コレクション Golang のガベージ コレクターは同時マークスイープ (concurrentmark-s) に基づいています。

JavaScript と WebSocket を使用してリアルタイム オンライン注文システムを実装する方法の紹介: インターネットの普及とテクノロジーの進歩に伴い、ますます多くのレストランがオンライン注文サービスを提供し始めています。リアルタイムのオンライン注文システムを実装するには、JavaScript と WebSocket テクノロジを使用できます。 WebSocket は、TCP プロトコルをベースとした全二重通信プロトコルで、クライアントとサーバー間のリアルタイム双方向通信を実現します。リアルタイムオンラインオーダーシステムにおいて、ユーザーが料理を選択して注文するとき

JavaScript チュートリアル: HTTP ステータス コードを取得する方法、特定のコード例が必要です 序文: Web 開発では、サーバーとのデータ対話が頻繁に発生します。サーバーと通信するとき、多くの場合、返された HTTP ステータス コードを取得して操作が成功したかどうかを判断し、さまざまなステータス コードに基づいて対応する処理を実行する必要があります。この記事では、JavaScript を使用して HTTP ステータス コードを取得する方法を説明し、いくつかの実用的なコード例を示します。 XMLHttpRequestの使用

JavaScript と WebSocket: 効率的なリアルタイム天気予報システムの構築 はじめに: 今日、天気予報の精度は日常生活と意思決定にとって非常に重要です。テクノロジーの発展に伴い、リアルタイムで気象データを取得することで、より正確で信頼性の高い天気予報を提供できるようになりました。この記事では、JavaScript と WebSocket テクノロジを使用して効率的なリアルタイム天気予報システムを構築する方法を学びます。この記事では、具体的なコード例を通じて実装プロセスを説明します。私たちは

JavaScript で HTTP ステータス コードを取得する方法の紹介: フロントエンド開発では、バックエンド インターフェイスとの対話を処理する必要があることが多く、HTTP ステータス コードはその非常に重要な部分です。 HTTP ステータス コードを理解して取得すると、インターフェイスから返されたデータをより適切に処理できるようになります。この記事では、JavaScript を使用して HTTP ステータス コードを取得する方法と、具体的なコード例を紹介します。 1. HTTP ステータス コードとは何ですか? HTTP ステータス コードとは、ブラウザがサーバーへのリクエストを開始したときに、サービスが
