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

推薦する

GZIP 圧縮 Tomcat と Web パフォーマンスの改善プロセス図

1. はじめに最近、あるプロジェクトに取り組んでいたのですが、サーバーからクライアントに返される J...

古典的なスネークゲームの JavaScript 実装

この記事では、古典的なスネークゲームを実装するためのJavaScriptの具体的なコードを参考までに...

Mysql8.0はソート問題を解決するためにウィンドウ関数を使用する

MySQL ウィンドウ関数の紹介MySQL は MySQL 8.0 以降、ウィンドウ関数をサポートし...

Nginx で Basic Auth ログイン認証を設定する方法

nginx でファイルサーバーを構築することもありますが、これは一般に公開されていますが、サーバーが...

MySQL データベース開発の 36 の原則 (要約)

序文これらの原則は実際の戦闘から要約されています。あらゆる原則の背後には血なまぐさい教訓があるこれら...

スライダー検証コードを実装するJavaScript

この記事では、スライダー検証コードを実装するためのJavaScriptの具体的なコードを参考までに共...

HTML テーブル境界制御実装コード

一般的に、テーブルを使用する場合は、常に <table border="1"...

Mysql は最大接続数を表示し、最大接続数を変更します

MySQL 最大接続数の表示と最大接続数の変更1. 最大接続数を確認する '%max_con...

CSS3は光る境界線効果を実現します

操作効果: html <!-- この要素は表示されません。DOM は JavaScript に...

フレックスレイアウトにおける画像変形の解決策の詳細な説明

フレックス レイアウトは現在よく使用されるレイアウト方法ですが、場合によっては小さな問題が発生するこ...

jsを使用して写真をアップロードする機能を実現する

フロントエンドで画像をアップロードする原理は、入力 type="file" タグ...

HTML入門チュートリアル HTMLタグ記号をすぐにマスター

補足<br />HTML について何も知らず、HTML の始め方がまだわからない場合は、...

MySQL ビューの原理と使用法の詳細な分析

序文: MySQL では、ビューはおそらく最も一般的に使用されるデータベース オブジェクトの 1 つ...

Vue が学ぶべき知識ポイント: forEach() の使用

序文フロントエンド開発では、目的のコンテンツを取得するためにループをトラバースする必要がある状況に頻...

自動ウェブページ更新と自動ジャンプのサンプルコード

ウェブページの自動更新: <head></head> の間に次のコードを追加...