ホームページ バックエンド開発 C#.Net チュートリアル .Net ガベージ コレクションとラージ オブジェクトの処理

.Net ガベージ コレクションとラージ オブジェクトの処理

Feb 17, 2017 am 11:17 AM

英語の原文: Maoni Stephens、編集者: Zhao Yukai (@玉凯Sir)

CLR ガベージ コレクターは、オブジェクトが占有するスペースのサイズに応じてオブジェクトを分割します。大きなオブジェクトと小さなオブジェクトの処理方法には大きな違いがあります。たとえば、メモリのデフラグ - メモリ内の大きなオブジェクトの移動にはコストがかかります。ガベージ コレクタが大きなオブジェクトをどのように処理するか、また大きなオブジェクトがプログラムのパフォーマンスにどのような影響を与えるかを調べてみましょう。

ラージ オブジェクト ヒープとガベージ コレクション

.Net 1.0 および 2.0 では、オブジェクトのサイズが 85000 バイトを超える場合、それはラージ オブジェクトとみなされます。この数値は、パフォーマンス最適化の経験に基づいています。オブジェクトによって要求されたメモリ サイズがこのしきい値に達すると、ラージ オブジェクト ヒープに割り当てられます。これはどういう意味ですか?これを理解するには、.Net ガベージ コレクション メカニズムを理解する必要があります。

ほとんどの人が知っているように、.Net GC は「世代」単位でデータを収集します。プログラムには、世代 0、世代 1、および世代 2 の 3 つの世代のオブジェクトがあります。世代 0 が最も若いオブジェクトで、世代 2 のオブジェクトの生存時間が最も長くなります。 GC はパフォーマンス上の理由から世代ごとにガベージを収集します。通常、オブジェクトは世代 0 でリサイクルされます。たとえば、ASP.NET プログラムでは、各要求に関連付けられたオブジェクトは要求の最後にリサイクルされる必要があります。リサイクルされていないオブジェクトは第 1 世代のオブジェクトになります。つまり、第 1 世代のオブジェクトは、常駐メモリ オブジェクトと、もうすぐ消滅するオブジェクトとの間のバッファになります。

世代の観点から見ると、大きなオブジェクトは第 2 世代のリサイクル中にのみ処理されるため、大きなオブジェクトは第 2 世代のオブジェクトに属します。ある世代のガベージコレクションが実行されると、それよりも若い世代のガベージコレクションも同時に実行されます。例: 第 1 世代のガベージ コレクションが実行されると、第 1 世代と第 0 世代のオブジェクトが同時にリサイクルされます。第 2 世代のガベージ コレクションが実行されると、第 1 世代と第 0 世代のオブジェクトがリサイクルされます。

Generation は、メモリ領域を区別するためのガベージ コレクターの論理ビューです。物理ストレージの観点から見ると、オブジェクトはさまざまなマネージド ヒープに割り当てられます。マネージド ヒープは、オペレーティング システムからガベージ コレクターによって (Windows API VirtualAlloc を呼び出して) 割り当てられるメモリ領域です。 CLR がメモリをロードすると、ラージ オブジェクト ヒープ (LOH – ラージ オブジェクト ヒープ) とスモール オブジェクト ペア (SOH – スモール オブジェクト ヒープ) の 2 つのマネージド ヒープが初期化されます。

メモリ割り当てリクエストは、マネージド オブジェクトを対応するマネージド ヒープに配置することです。オブジェクトのサイズが 85000 バイト未満の場合は SOH に配置され、それ以外の場合は LOH に配置されます。

SOHの場合、オブジェクトはガベージコレクションを実行した後、次の世代に入ります。つまり、最初にガベージ コレクションが実行されたときに、生き残ったオブジェクトが第 2 世代に入る場合、そのオブジェクトが 2 回目のガベージ コレクション後にまだガベージ コレクションされていない場合、そのオブジェクトは第 2 世代のオブジェクトになります。 object は最も古いオブジェクトであり、世代は増加しません。

ガベージ コレクションがトリガーされると、ガベージ コレクターは小さなオブジェクト ヒープをデフラグし、残っているオブジェクトをまとめて移動します。ラージ オブジェクト ヒープに関しては、メモリの移動コストが高いため、CLR チームは、メモリを使用する次のラージ オブジェクトの要求を満たすために、それらをクリアし、リサイクルされたオブジェクトのリストを作成することを選択しました。隣接するガベージ オブジェクトは A にマージされます。メモリの空きブロック。

ラージ オブジェクト ヒープは .Net 4.0 までデフラグされないことに常に注意してください。ただし、将来的にはデフラグされる可能性があります。したがって、大きなオブジェクトを割り当て、それらを移動したくない場合は、fixed ステートメントを使用できます。

次のスモール オブジェクト ヒープ SOH のリサイクル図



上の図では、最初のガベージ コレクションの前に 4 つのオブジェクト obj0 ~ 3 があり、最初のガベージ コレクションの後、obj1 と obj3 がリサイクルされます。 、同時に obj2 と obj0 が一緒に移動され、2 回目のガベージ コレクションの前に 3 つのオブジェクト obj4 ~ 6 が割り当てられ、2 回目のガベージ コレクションの後、obj2 と obj5 がリサイクルされ、obj4 と obj6 が obj0 の隣に移動されました。

下の図はラージオブジェクトヒープLOHリサイクルの概略図です



ガベージコレクションが実行される前に、最初の2番目のオブジェクトの後に合計4つのオブジェクトobj0-3があることがわかります。生成ガベージ コレクション、obj1 と obj2 がリサイクルされました。obj1 と obj2 が占有していた領域は、obj4 がメモリ割り当てを申請したときに、同時に割り当てられました。 、記憶の断片が残った。このフラグメントのサイズが 85000 バイト未満の場合、このプログラムのライフサイクル中、このフラグメントを再度使用することはできません。

適用するラージ オブジェクト領域を収容するのに十分な空きメモリがラージ オブジェクト ヒープにない場合、CLR はまずオペレーティング システムからメモリを適用しようとします。アプリケーションが失敗すると、2 番目のメモリがトリガーされます。世代をリサイクルしてメモリの一部を解放しようとします。

第 2 世代のガベージ コレクション中に、不要なメモリは VirtualFree を通じてオペレーティング システムに返すことができます。返品プロセスについては、以下の画像をご覧ください:



大きな物品はいつリサイクルされますか?

大きなオブジェクトをいつリサイクルするかを議論する前に、まず通常のガベージ コレクション操作がいつ実行されるかを見てみましょう。ガベージ コレクションは次の状況で発生します:

1. 要求されたスペースが世代 0 のメモリ サイズまたはラージ オブジェクト ヒープのしきい値を超えている場合、ほとんどのマネージド ヒープ ガベージ コレクションが発生します。

2. Collect メソッドを呼び出すとき、GC.Collect メソッドを呼び出すときに GC.MaxGeneration パラメーターが渡されると、ラージ オブジェクト ヒープのガベージ コレクションを含むすべての世代オブジェクトのガベージ コレクションが実行されます

3。システムにメモリが不足している場合、アプリケーションがメモリ不足の通知を送信したとき

4. ガベージ コレクション アルゴリズムが第 2 世代のリサイクルが有効であると判断した場合、第 2 世代のガベージ コレクションがトリガーされます

5。オブジェクト ヒープに領域サイズのしきい値プロパティがある場合、特定の世代にオブジェクトを割り当て、その世代のしきい値近くまで合計メモリ量を増やすか、この世代のヒープ サイズがヒープしきい値を超えるオブジェクトを割り当てる場合、ガベージコレクションが発生します。したがって、スモール オブジェクトまたはラージ オブジェクトを割り当てると、世代 0 ヒープまたはラージ オブジェクト ヒープのしきい値が消費されます。ガベージ コレクターがオブジェクトの世代を世代 1 または世代 2 に増やすと、世代 1 と世代 2 のしきい値が消費されます。これらのしきい値は、プログラムの実行中に動的に変化します。

ラージ オブジェクト ヒープのパフォーマンスへの影響

まず、ラージ オブジェクトを割り当てるコストを見てみましょう。 CLR が新しいオブジェクトごとにメモリを割り当てるときは、メモリがクリアされ、他のオブジェクトによって使用されないようにする必要があります (I give out はクリアされます)。これは、割り当てのコストがクリアのコストによって完全に制御されることを意味します (割り当て中にガベージ コレクションがトリガーされない限り)。 1 バイトをクリアするのに 2 サイクルかかる場合、最小の大きなオブジェクトをクリアするには 170,000 サイクルかかることになります。通常、非常に大きなオブジェクトを割り当てることはありません。たとえば、2GHz のマシンに 16M のオブジェクトを割り当てると、メモリがクリアされるまでに約 16 ミリ秒かかります。価格が高すぎます。

リサイクルにかかる費用を見てみましょう。前述したように、大きなオブジェクトは 2 世代のオブジェクトと一緒にリサイクルされます。大きなオブジェクトまたは第 2 世代のオブジェクトが占めるスペースがしきい値を超えると、第 2 世代のオブジェクトのリサイクルがトリガーされます。ラージ オブジェクト ヒープがしきい値を超えたために世代 2 のリサイクルがトリガーされた場合、世代 2 のオブジェクト ヒープ自体にはリサイクルできるオブジェクトがあまりありません。第 2 世代ヒープにオブジェクトがそれほど多くない場合、これは大きな問題ではありません。ただし、第 2 世代のヒープが大きく、多くのオブジェクトがある場合、第 2 世代の過剰なリサイクルによりパフォーマンスの問題が発生します。ラージ オブジェクトを一時的に割り当てた場合、ガベージ コレクションの実行に時間がかかります。つまり、ラージ オブジェクトを使用し続けた後、ラージ オブジェクトを解放すると、パフォーマンスに大きな悪影響が生じます。

ラージ オブジェクト ヒープ上の巨大なオブジェクトは通常、配列です (1 つのオブジェクトが非常に大きい場合がまれにあります)。オブジェクト内の要素が強参照である場合、コストは非常に高くなります。要素間に相互参照がない場合、ガベージ コレクション中に配列全体を走査する必要はありません。例: 配列を使用してバイナリ ツリーのノードを保存します。1 つの方法は、ノード内の左右のノードを強く参照することです:

class Node
{
Data d;
Node left;
Node right;
}
 
Node[] binaryTree = new Node[num_nodes];
ログイン後にコピー

num_nodes が大きい数である場合、各ノードは次の場所で表示する必要があることを意味します。少なくとも 2 つの参照要素。別の方法は、左右のノード要素の配列インデックス番号をノードに保存することです


class Node
{
Data d;
uint left_index;
uint right_index;
}
ログイン後にコピー

この場合、要素間の参照関係は binaryTree[left_index] を通じて取得できます。 。ガベージ コレクターは、ガベージ コレクションを実行するときに関連する参照要素を確認する必要がなくなりました。

ラージ オブジェクト ヒープのパフォーマンス データを収集する

ラージ オブジェクト ヒープに関連するパフォーマンス データを収集するには、いくつかの方法があります。これらの方法を説明する前に、ラージ オブジェクト ヒープに関連するパフォーマンス データを収集する必要がある理由について説明しましょう。

特定の側面でパフォーマンス データの収集を開始するとき、この側面でパフォーマンスのボトルネックの証拠がすでに見つかっているか、すべての側面を検索しても問題が見つからない可能性があります。

.Net CLR メモリ パフォーマンス カウンターは、通常、パフォーマンスの問題を探すときに最初に検討する必要があるツールです。 LOH に関連するカウンターには、第 2 世代のコレクション (第 2 世代のヒープ コレクションの数) とラージ オブジェクト ヒープ サイズが含まれます。第 2 世代のコレクションは、プロセスの開始以降に発生した第 2 世代のガベージ コレクション操作の数を示します。ラージ オブジェクト ヒープ サイズ カウンタは、空き領域を含むラージ オブジェクト ヒープの現在のサイズを示します。このカウンタは、メモリが割り当てられるたびではなく、ガベージ コレクション操作の後に更新されます。

Windows パフォーマンス カウンターで .Net CLR メモリ関連のパフォーマンス データを観察するには、以下の図を参照してください


プログラムを通じてこれらのカウンターの値をクエリすることもできます。多くの人は、パフォーマンスのボトルネックを見つけるためにプログラムを通じてパフォーマンス カウンターを収集しています。

もちろん、デバッガー Winddbg を使用してラージ オブジェクト ヒープを観察することもできます。

最後の注意: これまでのところ、ラージ オブジェクト ヒープはガベージ コレクションの一部としてデフラグされていませんが、これは clr の実装の詳細にすぎず、プログラム コードはこの機能に依存すべきではありません。オブジェクトがガベージ コレクターによって移動されないようにする場合は、fixed ステートメントを使用します。

元のアドレス: http://www.php.cn/

上記は .Net ガベージ コレクションとラージ オブジェクト処理の内容です。その他の関連コンテンツについては、PHP 中国語に注意してください。ウェブサイト (www.php.cn)!


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

ホットAIツール

Undresser.AI Undress

Undresser.AI Undress

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

AI Clothes Remover

AI Clothes Remover

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

Undress AI Tool

Undress AI Tool

脱衣画像を無料で

Clothoff.io

Clothoff.io

AI衣類リムーバー

AI Hentai Generator

AI Hentai Generator

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

ホットツール

メモ帳++7.3.1

メモ帳++7.3.1

使いやすく無料のコードエディター

SublimeText3 中国語版

SublimeText3 中国語版

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

ゼンドスタジオ 13.0.1

ゼンドスタジオ 13.0.1

強力な PHP 統合開発環境

ドリームウィーバー CS6

ドリームウィーバー CS6

ビジュアル Web 開発ツール

SublimeText3 Mac版

SublimeText3 Mac版

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

C# の雇用の見通しはどのようなものですか? C# の雇用の見通しはどのようなものですか? Oct 19, 2023 am 11:02 AM

初心者でも経験豊富なプロフェッショナルでも、C# をマスターすることでキャリアへの道が開かれます。

いくつかの .NET オープンソース AI および LLM 関連プロジェクト フレームワークを共有する いくつかの .NET オープンソース AI および LLM 関連プロジェクト フレームワークを共有する May 06, 2024 pm 04:43 PM

現在、人工知能(AI)技術の開発は本格化しており、さまざまな分野で大きな可能性と影響力を発揮しています。本日、Dayao は、参考にしていただけるよう、4 つの .NET オープン ソース AI モデル LLM 関連プロジェクト フレームワークを共有します。 https://github.com/YSGStudyHards/DotNetGuide/blob/main/docs/DotNet/DotNetProjectPicks.mdSemanticKernelSemanticKernel は、OpenAI、Azure などの大規模言語モデル (LLM) を統合するように設計されたオープン ソース ソフトウェア開発キット (SDK) です。

開発者向けの .NET パフォーマンス最適化テクノロジ 開発者向けの .NET パフォーマンス最適化テクノロジ Sep 12, 2023 am 10:43 AM

.NET 開発者は、高品質のソフトウェアを提供するために機能とパフォーマンスを最適化することの重要性を認識する必要があります。提供されたリソースを巧みに活用し、Web サイトの読み込み時間を短縮することで、ユーザーに快適なエクスペリエンスを提供するだけでなく、インフラストラクチャのコストも削減できます。

Java フレームワークと .NET フレームワークのパフォーマンスの違い Java フレームワークと .NET フレームワークのパフォーマンスの違い Jun 03, 2024 am 09:19 AM

同時実行性の高いリクエスト処理の点では、.NETASP.NETCoreWebAPI は JavaSpringMVC よりも優れたパフォーマンスを発揮します。その理由としては、AOT の早期コンパイルにより起動時間が短縮され、開発者がオブジェクト メモリの割り当てと解放を行うため、より洗練されたメモリ管理が行われます。

c#.netインタビューの質問と回答:専門知識を高める c#.netインタビューの質問と回答:専門知識を高める Apr 07, 2025 am 12:01 AM

C#.NETインタビューの質問と回答には、基本的な知識、コアの概念、高度な使用が含まれます。 1)基本知識:C#は、Microsoftが開発したオブジェクト指向言語であり、主に.NETフレームワークで使用されています。 2)コアの概念:委任とイベントは動的な結合方法を可能にし、LINQは強力なクエリ関数を提供します。 3)高度な使用:非同期プログラミングは応答性を向上させ、式ツリーは動的コード構造に使用されます。

高度なC#.NETチュートリアル:次のシニア開発者インタビューをエース 高度なC#.NETチュートリアル:次のシニア開発者インタビューをエース Apr 08, 2025 am 12:06 AM

C#シニア開発者とのインタビューでは、非同期プログラミング、LINQ、.NETフレームワークの内部作業原則などのコア知識をマスターする必要があります。 1.非同期プログラミングは、非同期を通じて操作を簡素化し、アプリケーションの応答性を向上させるのを待ちます。 2.LinqはSQLスタイルでデータを操作し、パフォーマンスに注意を払います。 3.ネットフレームワークのCLRはメモリを管理し、ガベージコレクションに注意して使用する必要があります。

C#.NET:コアの概念とプログラミングの基礎を探る C#.NET:コアの概念とプログラミングの基礎を探る Apr 10, 2025 am 09:32 AM

C#は、Microsoftによって開発された最新のオブジェクト指向プログラミング言語であり、.NETフレームワークの一部として開発されています。 1.C#は、カプセル化、継承、多型を含むオブジェクト指向プログラミング(OOP)をサポートしています。 2。C#の非同期プログラミングは非同期を通じて実装され、適用応答性を向上させるためにキーワードを待ちます。 3. LINQを使用してデータ収集を簡潔に処理します。 4.一般的なエラーには、null参照の例外と、範囲外の例外インデックスが含まれます。デバッグスキルには、デバッガーと例外処理の使用が含まれます。 5.パフォーマンスの最適化には、StringBuilderの使用と、不必要な梱包とボクシングの回避が含まれます。

C# 開発でオブジェクトのシリアル化と逆シリアル化を処理する方法 C# 開発でオブジェクトのシリアル化と逆シリアル化を処理する方法 Oct 10, 2023 pm 06:07 PM

C# 開発でオブジェクトのシリアル化と逆シリアル化を処理する方法には、特定のコード サンプルが必要です。C# 開発では、オブジェクトのシリアル化と逆シリアル化は非常に重要な概念です。シリアル化は、オブジェクトをネットワーク経由で送信したり、ディスクに保存したりできる形式に変換します。一方、逆シリアル化は、シリアル化されたデータを元のオブジェクトに変換します。この記事では、C# でオブジェクトのシリアル化と逆シリアル化を処理する方法を紹介し、いくつかの具体的なコード例を示します。シリアル化と逆シリアル化に Json.NET ライブラリを使用する Json.NET は人気のある

See all articles