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を使用してドメイン名ベースの仮想ホストを構成する

推薦する

Dockerデータを完全にクリーンアップする方法

目次定期的に剪定するミラーエビクションコンテナのクリーンアップネットワークソート体積の蒸発完全にクリ...

IE、Firefox、Chromeブラウザではスペースの表示が異なります

&nbsp;&nbsp;IE、Firefox、Chrome ブラウザでの表示効果は、...

Vue で jsx 構文を正しく使用する方法

目次序文仮想DOM仮想DOMとは仮想DOMの利点レンダリング関数とは何ですか? jsx Vue3 で...

MySQLのトランザクション特性とレベル原則の分析

1. トランザクションとは何ですか?データベース トランザクション (略称: トランザクション) は...

Linux のスケジュールされたタスクの crontab のインストールと使用の詳細な説明

crontabをインストールするyum install crontabs CentOS 7が付属して...

MySQL データ型 DECIMAL の使用方法の詳細な説明

MySQL DECIMALデータ型は、データベースに正確な数値を保存するために使用されます。会計シス...

HTMLテーブルではテーブルの外側の境界線のみが表示されます

質問があります。Dreamweaver で、3 行 1 列のログイン フォーム (ログイン、登録、パ...

マークアップ言語 - リスト

標準化されたデザインソリューション - マークアップ言語とスタイルマニュアルWeb 標準ソリューショ...

バックエンドから返される 100,000 個のデータをフロントエンドでより適切に表示するにはどうすればよいですか?

目次予備作業バックエンド構築フロントエンドページダイレクトレンダリングsetTimeout ページン...

Vue はユーザーのログイン状態を維持します (さまざまなトークン保存方法)

目次クッキーの設定方法クッキーのデメリット: LocalStorage と SessionStora...

WeChatミニプログラムはどのようにしてユーザー情報とユーザーの電話番号を同時に取得するのか

今日ログインページを書いていたとき、個人情報と携帯電話番号を認証する必要がありましたが、ページにボタ...

Vueでタイマーをエレガントにクリアする方法

目次序文最適化派生的な質問: beforeDestroy はトリガーされませんか?序文タイマーをクリ...

MySQL 8.0.15 圧縮版インストール グラフィック チュートリアル

この記事では、参考までにMySQL 8.0.15圧縮版のインストール方法を紹介します。具体的な内容は...

jQuery を使用してカルーセル効果を実装する

この記事では、jQueryでカルーセルチャートを実装するための具体的なコードを参考までに共有します。...

Linux プログラムの実行中に動的ライブラリをロードできない場合の解決策

Linux でダイナミック ライブラリをロードできません次のような異常事態が発生した場合./test...