ホームページ >ウェブフロントエンド >jsチュートリアル >JavaScriptのメモリ解放問題を詳しく解説_JavaScriptスキル

JavaScriptのメモリ解放問題を詳しく解説_JavaScriptスキル

WBOY
WBOYオリジナル
2016-05-16 16:18:381374ブラウズ

この記事では、JavaScript と IE ブラウザーによるメモリ管理と解放のタイミングと方法について詳しく説明します。フロントエンド開発者の参考になれば幸いです。

メモリ解放の例

コードをコピーします コードは次のとおりです:

<スクリプト言語="JavaScript">


CollectGarbage は IE の固有の属性であり、メモリを解放するために使用されます。使用方法は、変数または参照オブジェクトを null に設定するか、削除してから解放アクションを実行する必要があります。

CollectGarbage を実行する前に、2 つの前提条件を認識しておく必要があります:

参考 - オブジェクトは、それが存在するコンテキストの外では無効になります。
・ グローバルオブジェクトは使用(参照)しないと無効になります。

コードをコピーします コードは次のとおりです:

//------------------------------------------------ ----------
//JavaScript オブジェクトの有効期限が切れるとき
//------------------------------------------------ ----------
関数 testObject() {
var _obj1 = 新しいオブジェクト();
}
function testObject2() {
var _obj2 = 新しいオブジェクト();
return _obj2;
}
// 例 1
testObject();
// 例 2
testObject2()
//例 3
var obj3 = testObject2();
obj3 = null;
//例 4
var obj4 = testObject2();
var arr = [obj4];
obj3 = null;
arr = [];

これらの 4 つの例では:
- 「例 1」では関数 testObject() で _obj1 を構築しますが、関数が終了すると関数のコンテキストから離れるため、_obj1 は無効になります。

- 「例 2」では、オブジェクト _obj2 も testObject2() で構築され、渡されます。そのため、オブジェクトは「関数の外部」コンテキスト (およびライフサイクル) を持ちます。ただし、関数の戻り値は次のとおりです。他の変数は「保持」されるため、_obj2 もすぐに無効になります。

・「例3」では、testObject2()で構築した_obj2を外部変数obj3に保持していますが、このとき「obj3=null」行が有効になるまでは参照関係がなくなるため_obj2は無効になります。 。

- 例 3 と同じ理由で、「例 4」の _obj2 はコードの「arr=[]」行以降で無効になります。

ただし、オブジェクトの「無効化」は、オブジェクトが「解放」されるまで待機しません。 JavaScript ランタイム環境内では、オブジェクトがいつリリースされるかをユーザーに正確に伝える方法はありません。これは、JavaScript のメモリ リサイクル メカニズムに依存しています。 ——この戦略は、.NET のリサイクル メカニズムに似ています。

上記の Excel 操作サンプルコードでは、オブジェクトの所有者、つまり「EXCEL.EXE」の処理は「ActiveX オブジェクトのインスタンスの解放」後にのみ発生します。ファイル ロックとオペレーティング システムのアクセス許可資格情報はプロセスに関連しています。したがって、オブジェクトが「解放」されずに単に「無効化」された場合、ファイルを処理し、オペレーティング システムの権限資格情報を参照する他のプロセスに問題が発生します。

——これは JavaScript または COM メカニズムのバグであると言う人もいます。実際には、いいえ、これは独立した問題ではなく、OS、IE、JavaScript 間の複雑な関係によって引き起こされます。

Microsoft は、この問題を解決するための戦略を明らかにしました。それは、メモリ リサイクル プロセスを積極的に呼び出すことです。

CollectGarbage() プロセス (通常は GC プロセスと呼ばれます) は、(Microsoft) JScript で提供されており、現在の IE の「無効なオブジェクト例外」をクリーンアップするために使用されます。オブジェクトのデストラクタプロセス。

上記の例で GC プロセスを呼び出すコードは次のとおりです:

コードをコピーします コードは次のとおりです:
//------------------------------------------------ ----------
// ActiveX オブジェクトを扱う場合、GC プロセスの標準呼び出しメソッド
//------------------------------------------------ ----------
関数 writeXLS() {
//(省略…)
Excel.Quit();
Excel = null;
setTimeout(CollectGarbage, 1);
}

コードの最初の行は、excel.Quit() メソッドを呼び出して Excel プロセスを終了して終了します。この時点では、JavaScript 環境は Excel オブジェクトのインスタンスを保持しているため、Excel プロセスは実際には終了しません。

コードの 2 行目では、Excel を null にしてオブジェクト参照をクリアし、オブジェクトを「無効化」します。ただし、オブジェクトはまだ関数コンテキスト内にあるため、GC プロセスが直接呼び出された場合、オブジェクトは依然としてクリーンアップされません。

コードの 3 行目では、setTimeout() を使用して CollectGarbage 関数を呼び出し、時間間隔を「1」に設定します。これにより、writeXLS() 関数の実行後にのみ GC プロセスが発生します。このように、Excel オブジェクトは「GC でクリーンアップできる」という 2 つの条件 (参照がない、コンテキストを離れる) を満たしています。

GC 処理の使用は、ActiveX オブジェクトを使用した JS 環境で非常に効果的です。潜在的な ActiveXObject には、XML、VML、OWC (Office Web コンポーネント)、フラッシュ、さらには JS の VBArray などがあります。この観点から、ajax アーキテクチャは XMLHTTP を使用し、「ページ切り替えなし」機能も満たす必要があるため、適切なタイミングで GC プロセスを積極的に呼び出すと、より効率的な UI エクスペリエンスが得られます。

実は、GC処理を利用したとしても、上記のExcelの問題は完全に解決されるわけではありません。 IE はアクセス許可の資格情報もキャッシュするためです。ページの認証情報を更新する唯一の方法は、「新しいページに切り替える」ことです。

実際、前述の SPS プロジェクトで使用したメソッドは GC ではなく、次のコードです。

コードをコピーします コードは次のとおりです:

//------------------------------------------------ ----------
// ActiveX オブジェクトの処理時に使用されるページ切り替えコード
//------------------------------------------------ ----------
関数 writeXLS() {
//(省略…)
Excel.Quit();
Excel = null;
// 次のコードは、MSDN で提供されているメソッドである Excel 呼び出しのバグを解決するために使用されます。 // setTimeout(CollectGarbage, 1);
// Web ページの信頼済みステータスをクリア (または同期) できないため、
では SaveAs() などのメソッドが使用されます。 // 次回呼び出されたときは無効です。
location.reload();
}

マニュアルの削除演算子の説明

参照は、オブジェクトからプロパティを削除するか、配列から要素を削除します。

式を削除

expression パラメータは有効な JScript 式で、通常はプロパティ名または配列要素です。

説明

expression の結果がオブジェクトで、expression で指定されたプロパティが存在し、そのオブジェクトが削除を許可していない場合は、false を返します。

その他すべての場合、true を返します。

最後に、GC についての補足: IE フォームが最小化されている場合、IE は CollectGarbage() 関数を 1 回積極的に呼び出します。これにより、IE ウィンドウを最小化した後のメモリ使用量が大幅に改善されます

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。