JSメモリ空間の詳細な説明

JSメモリ空間の詳細な説明

概要

変数オブジェクトとヒープメモリ

var a = 20;
var b = 'abc';
var c = true;
var d = {m:20} 

長い間、JS を学ぶ上でメモリ空間の概念はそれほど重要ではないと思っていました。しかし、後になって JS の基礎を整理し直してみると、漠然とした理解のため、理解できていないことがたくさんあることに気づきました。たとえば、最も基本的な参照データ型と参照渡しとは何でしょうか?たとえば、シャロー コピーとディープ コピーの違いは何でしょうか?クロージャやプロトタイプなどもあります。

そのため、JS をより深く理解したいのであれば、メモリ空間を明確に理解する必要があることに徐々に気づきました。

1. スタックとヒープ

注: スタックはスタックとも呼ばれます

C/C++ とは異なり、JavaScript ではスタック メモリとヒープ メモリを厳密に区別しません。したがって、すべての JavaScript データはヒープ メモリに格納されていると大まかに理解できます。ただし、JavaScript の実行コンテキストなど、一部のシナリオでは、依然としてスタック データ構造の考え方に基づいて処理する必要があります (実行コンテキストについては次の記事でまとめます)。実行コンテキストはスタックを論理的に実装します。したがって、スタック データ構造の原理と特性を理解することは依然として非常に重要です。

スタックがどのようにアクセスされるかを簡単に理解するために、ピンポンボックスとの類推で分析することができます。下の画像の左側に示すように。

ピンポンボックスとスタックの類似点

ピンポンボールの保存方法は、スタック内でのデータの保存およびアクセス方法とまったく同じです。箱の最上層にあるピンポン玉5は最後に入れる必要がありますが、最初に使用することもできます。一番下のピンポン玉 1 を使いたい場合、ピンポン玉 1 が箱の最上層にくるように、上の 4 つのピンポン玉を取り出す必要があります。これは、スタック スペースの先入れ後出しと後入れ先出しの特性です。図はスタックスペースの格納原理を詳細に示しています。

ヒープがデータを保存し、アクセスする方法は、本棚と本の方法と非常に似ています。

本は本棚にきちんと収納されていますが、本のタイトルさえわかっていれば、箱からピンポン玉を全部取り出して真ん中のピンポン玉を取り出す必要がなく、欲しい本を簡単に取り出すことができます。たとえば、JSON 形式のデータでは、保存するキーと値のペアは順序付けされていない場合があります。順序が異なっていても使用には影響しないため、書籍の名前のみに注意する必要があります。

2. 変数オブジェクトと基本データ型

JavaScript 実行コンテキストが生成されると、変数オブジェクトと呼ばれる特別なオブジェクトが作成されます (詳細は次の記事で実行コンテキストと合わせてまとめます)。JavaScript の基本的なデータ型は、変数オブジェクトに格納されることが多いです。

厳密に言えば、変数オブジェクトもヒープメモリに格納されますが、変数オブジェクトの特殊な機能のため、理解する際にはヒープメモリと区別する必要があります。

基本データ型は単純なデータ セグメントです。JavaScript には、Undefined、Null、Boolean、Number、String の 5 つの基本データ型があります。基本データ型は、変数に格納されている実際の値を直接操作できるため、値によってアクセスされます。

3. 参照データ型とヒープメモリ

他の言語とは異なり、配列などの JS の参照データ型には固定サイズでない値があります。参照データ型の値は、ヒープ メモリに格納されるオブジェクトです。 JavaScript ではヒープ メモリ内の場所に直接アクセスできないため、オブジェクトのヒープ メモリ領域を直接操作することはできません。オブジェクトを操作する場合、実際には実際のオブジェクトではなくオブジェクト参照を操作します。したがって、参照型の値は参照によってアクセスされます。ここでの参照は、変数オブジェクトに格納されているアドレスとして大まかに理解でき、ヒープ メモリの実際の値に関連付けられています。

変数オブジェクトとヒープ メモリをよりよく理解するために、次の例と図を参考にしてください。

var a1 = 0; // 変数オブジェクト var a2 = 'this is string'; // 変数オブジェクト var a3 = null; // 変数オブジェクト var b = { m: 20 }; // 変数 b は変数オブジェクトに存在し、{m: 20} はヒープメモリ内のオブジェクトとして存在します var c = [1, 2, 3]; // 変数 c は変数オブジェクトに存在し、[1, 2, 3] はヒープメモリ内のオブジェクトとして存在します

上記の例の図解

したがって、ヒープ メモリ内の参照データ型にアクセスする場合、実際にはまず変数オブジェクトからオブジェクトのアドレス参照 (またはアドレス ポインター) を取得し、次にヒープ メモリから必要なデータを取得します。

JS のメモリ空間を理解した後、メモリ空間の特性を使用して参照型のいくつかの特性を検証できます。

フロントエンドの面接では、同様の質問によく遭遇します。

// デモ01.js
var a = 20;
var b = a;
30;

// この時点での a の値は何ですか?
// デモ02.js
var m = { a: 10, b: 20 }
var n = m;
ナ = 15;

// この時点での ma の値はいくらか

変数オブジェクト内のデータがコピーされると、システムは新しい変数に新しい値を自動的に割り当てます。 var b = a が実行されると、a と b の値は両方とも 20 に等しくなりますが、実際にはそれらは互いに独立しており、互いに影響を及ぼしません。詳細は画像をご覧ください。したがって、b の値を変更した後、a の値は変更されません。

デモ01図

demo02では、var n = mを使用してコピー参照型の操作を実行します。参照型をコピーすると、新しい変数に新しい値が自動的に割り当てられ、変数オブジェクトに保存されますが、違いは、この新しい値が参照型のアドレス ポインターにすぎないことです。アドレス ポインタが同じである場合、それらは互いに独立していますが、変数オブジェクトでアクセスされる特定のオブジェクトは実際には同じです。写真の通りです。

したがって、n を変更すると、m も変更されます。これが参照型の性質です。

デモ02図

記憶の観点から理解すると、ずっと簡単に感じるでしょう。さらに、これを基礎として、JavaScript の実行コンテキスト、スコープ チェーン、クロージャ、プロトタイプ チェーンなどの重要な概念を段階的に理解することもできます。残りについては今後の記事でゆっくりまとめていきますので、お楽しみに。

メモリ空間管理

JavaScript には自動ガベージコレクションのメカニズムがあるため、開発中にメモリの使用量を心配する必要はありません。メモリの割り当てとリサイクルは完全に自動で管理されます。しかし、私自身の開発経験に基づくと、メモリのメカニズムを理解することで、記述したコードの実行中に何が起こったのかを明確に理解できるようになり、よりパフォーマンスの高いコードを作成できるようになります。したがって、記憶を気にすることは非常に重要なことです。

JavaScript メモリライフサイクル

1. 必要なメモリを割り当てる

2. 割り当てられたメモリを使用する(読み取り、書き込み)

3. 不要になったら解放または返却する

理解しやすくするために、簡単な例を使ってこのサイクルを説明します。

var a = 20; // 数値変数用にメモリ領域を割り当てます alert(a + 100); // メモリを使用します var a = null; // 使用後にメモリ領域を解放します

1 番目と 2 番目のステップは簡単に理解できます。JavaScript は変数を定義するときにメモリの割り当てを完了します。 3 番目のステップであるメモリ領域の解放は、理解に重点を置く必要があるポイントです。

JavaScript には自動ガベージコレクション機構がありますが、この自動ガベージコレクション機構の原理は何でしょうか?実際のところ、それは非常に簡単で、使用されなくなった値を見つけて、それらが占有しているメモリを解放するだけです。ガベージ コレクターは、定期的に解放操作を実行します。

JavaScript で最もよく使用される方法は、マーク アンド スイープ アルゴリズムを使用して、使用されなくなったオブジェクトを見つけることです。したがって、 a = null実際には参照を解放するだけで、a に元々対応していた値は参照を失い、実行環境から抜け出します。この値は、ガベージ コレクターが次に操作を実行するときに見つかり、解放されます。適切なタイミングで逆参照を行うことは、ページのパフォーマンスを向上させる重要な方法です。

ローカルスコープでは、関数が実行されるとローカル変数は不要になるため、ガベージコレクターが簡単に判断してリサイクルすることができます。しかし、グローバル変数がメモリ領域を自動的に解放する必要があるタイミングを判断するのは困難です。そのため、開発では、パフォーマンスの問題を確実に回避するために、グローバル変数の使用を可能な限り避ける必要があります。ガベージコレクションのメカニズムについて詳しくは、「Advanced JavaScript Programming」のセクション4.3を読むことをお勧めします。

以上がJSメモリ空間の詳しい説明です。JSメモリ空間についてさらに詳しく知りたい方は、123WORDPRESS.COMの他の関連記事もぜひご覧ください!

以下もご興味があるかもしれません:
  • JavaScript のメモリ空間、割り当て、深いコピーと浅いコピーの詳細な説明
  • JavaScript のメモリリークを理解するための記事
  • NodeJs の高メモリ使用量のトラブルシューティング実戦記録
  • Node.js でメモリ効率の高いアプリケーションを作成する方法
  • JavaScript のガベージコレクションメカニズムとメモリ管理
  • 一般的な JS メモリ リークとその解決策の分析
  • JavaScript メモリ モデルの例の詳細な説明
  • JS によるメモリリークの例をいくつか分析する
  • JavaScriptのスタックメモリとヒープメモリの詳しい説明
  • JavaScript のメモリリークに対処する方法

<<:  Mysqlツリー再帰クエリの実装方法

>>:  nginxを使用してドメイン名ベースの仮想ホストを構成する

推薦する

Windows 10 でカスタムドメイン名をバインドするように Hexo と GitHub を構成する方法

Hexo は Windows 10 でカスタムドメイン名を GitHub にバインドしますまずドメイ...

MySQL ログトリガー実装コード

SQL文 ドロップトリガー もし sys_menu_edit が存在します。 各行のsys_menu...

Dockerを使用して開発環境を構築する方法を素早く習得します

プラットフォームが成長し続けるにつれて、プロジェクトの研究開発は、開発者向けのさまざまな外部環境、特...

Win10の明るさ調整効果を模倣するHTML+CSS+JSサンプルコード

HTML+CSS+JS で Win10 の明るさ調整効果を模倣コード <!doctypehtm...

HTML ページをズームアウトした後にスクロール バーを表示するためのサンプル コード

ここでは、HTML ページのサイズを縮小した後に下部にスクロール バーを表示し、スクロール バーをス...

nginxリバースプロキシによるセッション障害の問題の解決策

同僚から助けを求められました。バックエンド システムへのログインは成功したものの、システムには正常に...

IE ラベル LI テキスト折り返し問題について

私は長い間この問題に悩まされていましたが、検索してみたところ、実際にこの問題を解決した人がいることが...

コーディングスキルを向上させるためのJavaScriptのヒント

目次1. 一意の値をフィルタリングする2. 短絡評価2.1 シナリオ例3. ブール変換4. 文字列を...

Vue はクリックフリップ効果を実現します

参考までに、vueを使用してクリックフリップエフェクトを簡単に実装します。具体的な内容は次のとおりで...

SQL ROW_NUMBER() および OVER() メソッドのケーススタディ

構文フォーマット: row_number() over(partition by grouping ...

vue3.0+echarts は 3 次元の縦棒グラフを実現します

序文: Vue3.0はechartsの3次元縦棒グラフを実装します結果: 実装手順: 1. echa...

Docker実践: Pythonアプリケーションのコンテナ化

1. はじめにコンテナはサンドボックス メカニズムを使用して相互に分離します。コンテナ内にデプロイさ...

WeChatアプレットのスクロールビューが左右の連動を実現

この記事では、WeChatアプレットのスクロールビューの左右連動を実現するための具体的なコードを参考...

CSS3 カテゴリメニュー効果

CSS3 カテゴリ メニューの効果は次のとおりです。 html <html> <ヘ...

CSS クロスブラウザ スタイルのバグのデバッグについて

まず最初に、適切なブラウザを選択します。私が Chrome を選択したのは、その強力なデバッグ ツー...