C# 値型と参照型のメモリ管理
このブログでは、ソフトウェア開発プロセス中のパフォーマンスを向上させる方法に焦点を当てます。これは、ソフトウェア開発または研究開発プロセスにおける根深い問題です。この記事では、主に、ソフトウェア コードを作成するプロセスでの計算の仕組みを、メモリ割り当てとメモリ リサイクルという 2 つの側面から説明します。ここではメモリ管理のプロセスと方法を理解することで、メモリ管理に注目し、今後のソフトウェア開発に役立てることができます。
値の型には、int、float、double、bool、構造体、参照、オブジェクト インスタンスを表す変数が含まれます
参照の型には、クラスと配列、より特殊な参照型である文字列、オブジェクト
一般的には、値の型のストレージ (スタック内)クラスの値フィールド、クラスの参照フィールド、配列の要素など、参照に含まれる値型は除外されます。これらは参照とともに規制ヒープに格納されます。なぜヒープが規制ヒープに格納されるのか。制御ヒープについては、以下で詳しく説明します。
いくつかの概念:
仮想メモリ: 32 ビット コンピューターでは、各プロセスには 4G の仮想メモリがあります。
規制ヒープ (マネージドヒープ): 誰によって規制されていますか?もちろん、ガベージコレクターはガベージコレクターです。それを管理する方法については後述します。
役に立たないユニットコレクター: ガベージコレクターは、マネージドヒープの圧縮、参照アドレスの更新に加えて、マネージドヒープの情報リストなども維持します。
値型の格納に関しては、まず次のコードを見てください:
{
int age=20;
double給与=2000;
}
上で定義した2つの変数int ageはコンパイラに伝えます。年齢値を保存するために 4 バイトのメモリ領域を割り当てます。年齢値はスタックに保存されます。スタックは先入れ後出しのデータ構造であり、上位アドレスから下位アドレスに向かってデータを格納します。コンピュータのレジスタはスタック ポインタを保持しており、このポインタは常にスタックの一番下にある空き領域のアドレスを指します。int 型の値を定義すると、変数が値を超えるとスタック ポインタが 4 バイトのアドレスだけ減分されます。スコープ、スタック ポインタはそれに応じてアドレスを 4 バイトずつインクリメントします。したがって、スタックのパフォーマンスは非常に高くなります。
参照型のストレージを見てみましょう。まずコードを見てみましょう:
{
Customer customerA;
customerA=new Customer() //Customer インスタンスが 32 バイトを占有していると仮定します
}
上記のコード 最初の行は、最初に Customer 参照を宣言します。参照の名前は customerA で、スタック上にこの参照用の記憶領域を割り当てます。記憶領域のサイズは 1 つの参照のみを格納するため、4 バイトです。指す参照は、Customer インスタンスが格納されるスペース アドレスです。この時点では、customerA は特定のスペースを指すのではなく、スペースを割り当てるだけであることに注意してください。
2 行目の実行中、.net 環境はマネージド ヒープを検索して、クラスのインスタンスに割り当てられた最初の未使用の連続 32 バイト領域を見つけ、customerA がこの領域の先頭位置を指すように設定します。 (ヒープ スペースは低いものから高いものへと使用されます)。参照変数がスコープ外になると、スタック内の参照は無効になりますが、インスタンスはガベージ コレクターによってクリーンアップされるまでマネージド ヒープ内に残ります。
ここを注意深く読んでいる人は、参照型を定義するとき、オブジェクトを格納するのに十分な大きさのメモリ領域を見つけるためにヒープ全体を検索する必要があるのでしょうか?これは非常に非効率的でしょうか?十分な連続スペースがない場合はどうすればよいですか?今回は「監護権」についてです。ヒープはガベージ コレクターによって管理され、ガベージ コレクターが実行されると、.net は解放できるすべてのオブジェクトを解放し、他のオブジェクトを圧縮してから、すべての空き領域を結合してヒープの先頭に移動して連続ブロックを形成します。同時に他のモバイルオブジェクトへの参照を更新します。別のオブジェクト定義がある場合は、適切なスペースをすぐに見つけることができます。マネージド ヒープはスタックと同様に動作し、ヒープ ポインタを通じて領域を割り当て、再利用するようです。
上記は、.net のメモリ領域割り当ての管理プロセスと方法について説明しました。次に、メモリのリサイクル プロセスについて説明します。リソースのクリーンアップに関しては、2 つの概念と 3 つの方法について言及する必要があります。
2 つの概念は、マネージド リソースとアンマネージド リソースです。
マネージド リソースは .net Framework の CLR (Common Language Runtime) によって管理されます。アンマネージド リソースは CLR (Common Language Runtime) によって管理されません。
3 つのメソッドは、Finalize()、Dispose()、Close() です。
1. Finalize() は、アンマネージ リソースをクリアするデストラクター メソッドです。
クラスで定義:
public ClassName{
~ClassName()
{
//管理されていないリソースをクリーンアップします(ファイルやデータベース接続を閉じるなど)
}
}
Its機能 はい:
1. 運用上の不確実性。
ガベージコレクターによって管理され、ガベージコレクターが動作すると、このメソッドが呼び出されます。
2. 高パフォーマンスのオーバーヘッド。
ガベージ コレクターの仕組みは、オブジェクトが Finalize() メソッドを実行する場合、ガベージ コレクターが最初にそれを実行するとき、そのオブジェクトは特別なキューに置かれ、2 回目の実行まで削除されません。
3. 定義と呼び出しは表示できず、定義はデストラクターメソッドの形式になっています。
上記の特性に基づいて、クラスが本当に必要とする場合、または他の 2 つのメソッドと組み合わせて使用する場合を除き、Finalize() メソッドを実行しないことが最善です。
2. Dispose() メソッドは、マネージド リソースとアンマネージド リソースを含む、クリアする必要があるすべてのリソースをクリアできます。
は次のように定義されます:
public void Dispose()
{
//クリーンアップする必要があるリソース (マネージドリソースとアンマネージドリソースを含む) をクリーンアップします
System.GC.SuppressFinalize(this) //この文は非常に重要です。その理由については以下で説明します。
}
その特徴:
1. リソースを解放するには、クライアント コードでこのメソッドを明示的に呼び出す必要があります。
2. 最初の理由により、通常はバックアップが必要であり、このバックアップは通常デストラクター メソッドによって再生されます。
3. このメソッドを定義するクラスは、IDisposable インターフェイスを継承する必要があります。
4. 構文キーワード using は、Dispose() を呼び出すことと同じです。using を使用すると、デフォルトで Dispose() メソッドが呼び出されます。したがって、using を使用するクラスも IDisposable インターフェイスを継承する必要があります。
Dispose() メソッドはより柔軟で、リソースが不要になったときにすぐに解放します。これはリソースの最終的な破棄であり、これを呼び出すことは、オブジェクトが最終的に削除されることを意味します。
3. Close() メソッド。リソースのステータスを一時的に破棄し、将来使用される可能性があります。通常、管理されていないリソースを処理します。
は次のように定義されます:
public viod Close()
{
//ファイルやデータベース接続を閉じるなど、管理されていないリソースのステータスを設定します
}
その機能:
管理されていないリソースのステータスを設定しますリソース設定。通常はファイルまたはデータベース接続を閉じます。
以下は、コードを使用して各部分の機能を示す包括的で古典的な例です: (トラブルを避けるために、この例はインターネットから作成したものです。問題を説明するだけで、どう思いますか。このような古典的でわかりやすいコードを書いてくれたコードのオリジナルの作者に感謝する必要があります。
Dispose(true);
}
protected virtual void Dispose(bool disposing)
{
if (破棄)
{
// これは、「管理リソース」をクリーンアップするためのユーザー コード スニペットです。
~ResourceHolder()
{
Dispose(false) // これは「管理されていないリソース」をクリーンアップするためのものです
}
}
;上記のコードは、次の説明を必ずよく読んでください。古典的なコードです。読まないと後悔します。
ここで、ユーザーはメソッド Dispose(bool) ではなくメソッド Dispose() を呼び出す必要があることを明確にしておく必要があります。ただし、ここで実際にリリース作業を実行するメソッドは Dispose() ではなく、Dispose(bool) です。 ! なぜですか? コードをよく見てください。Dispose() では、パラメータが「true」の場合に、すべてのマネージド リソースとアンマネージド リソースがクリーンアップされることを覚えておく必要があります。先ほど「 デストラクター メソッドはアンマネージ リソースを解放するために使用されます。」と言いました。では、Dispose() でアンマネージ リソースを解放する作業を完了できるので、デストラクター メソッドは何に使用されますか? 実際、デストラクター メソッドの役割は次のとおりです。ただの「バックアップ」です!
なぜですか?
正式に言えば、「IDisposable」インターフェイスを実装するクラスは、プログラマがコード内でこのクラスのオブジェクト インスタンスを使用する限り、遅かれ早かれこのクラスの Dispose() メソッドを同時に呼び出す必要があります。マネージド リソースが使用されている場合、アンマネージド リソースも解放する必要があります。残念なことに、アンマネージド リソースを解放するコードがデストラクター メソッドに配置されている場合 (上記の例は "~ResourceHolder()" に対応します)。その場合、プログラマーはこのセクションを呼び出したいとします。 コードを解放することは不可能です (デストラクター メソッドはユーザーが呼び出すことができず、システム、正確には「ガベージ コレクター」によってのみ呼び出すことができるため)。上記の例が「アンマネージ リソースのユーザー コードをクリーンアップする」理由を知ってください。「Section」が ~ResourceHolder() ではなく Dispose(bool) にあるのです。プログラマーがこのメソッドを呼び出すのを忘れた場合、マネージド リソースには問題ありません。遅かれ早かれ、それらを収集するための「ガベージ コレクター」が登場します (しばらく遅れるだけです)。しかし、アンマネージド リソースについてはどうでしょうか。 CLR の制御下にないので、占有しているアンマネージ リソースは決して解放できないのでしょうか? もちろん、Dispose() を呼び出すのを忘れた場合でも、ガベージ コレクター" は、アンマネージ リソースを解放するために "破棄メソッド" も呼び出します! (もう 1 つナンセンスですが、プログラマが Dispose() を呼び出すことを覚えている場合、コード "System.GC.SuppressFinalize(this);" によって "つまり、プログラマが Dispose() メソッドを呼び出すのを忘れることを心配する必要はありません。
ホットAIツール

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

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

Undress AI Tool
脱衣画像を無料で

Clothoff.io
AI衣類リムーバー

Video Face Swap
完全無料の AI 顔交換ツールを使用して、あらゆるビデオの顔を簡単に交換できます。

人気の記事

ホットツール

メモ帳++7.3.1
使いやすく無料のコードエディター

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

ゼンドスタジオ 13.0.1
強力な PHP 統合開発環境

ドリームウィーバー CS6
ビジュアル Web 開発ツール

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

ホットトピック









定数は変数とも呼ばれ、一度定義されると、その値はプログラムの実行中に変更されません。したがって、変数を固定値を参照する定数として宣言できます。テキストとも呼ばれます。定数は、Const キーワードを使用して定義する必要があります。構文 C プログラミング言語で使用される定数の構文は次のとおりです - consttypeVariableName; (または) consttype*VariableName; さまざまなタイプの定数 C プログラミング言語で使用されるさまざまなタイプの定数は次のとおりです: 整数定数 - 例: 1,0 、34、4567 浮動小数点定数 - 例: 0.0、156.89、23.456 8 進数および 16 進数の定数 - 例: 16 進数: 0x2a、0xaa.. 8 進数

VS Code および Visual Studio C++ IntelliSense は、特に大規模なプロジェクトで作業している場合、ライブラリを選択できない場合があります。 #Include<wx/wx.h> の上にマウスを移動すると、「ソース ファイル 'string.h' を開けません」というエラー メッセージが表示され (「wx/wx.h」に応じて異なります)、オートコンプリート関数が応答しなくなることがあります。この記事では、VSCode および VSC++ IntelliSense が機能しない場合、またはライブラリを抽出できない場合の対処法を説明します。私のインテリセンスが C++ で動作しないのはなぜですか?大きなファイルを扱う場合、IntelliSense が機能しないことがあります。

エラー コード 8C230002 が原因で、Xbox でコンテンツを購入または視聴できませんか?一部のユーザーは、本体でコンテンツを購入または視聴しようとすると、引き続きこのエラーが発生します。申し訳ありませんが、Xbox サービスに問題があります。後でもう一度お試しください。この問題のヘルプが必要な場合は、www.xbox.com/errorhelp にアクセスしてください。ステータス コード: 8C230002 このエラー コードは通常、サーバーまたはネットワークの一時的な問題によって発生します。ただし、アカウントのプライバシー設定や保護者による制限など、他の理由により、特定のコンテンツの購入または表示が妨げられる場合があります。 Xbox エラー コード 8C230002 を修正する Xbox 本体でコンテンツを視聴または購入しようとしたときにエラー コード 8C が表示された場合

整数配列 Arr[] を入力として受け取ります。目標は、再帰的メソッドを使用して配列内の最大要素と最小要素を見つけることです。再帰を使用しているため、長さ = 1 に達するまで配列全体を反復処理し、基本ケースを形成する A[0] を返します。それ以外の場合、現在の要素は現在の最小値または最大値と比較され、その値は後続の要素に対して再帰的に更新されます。この場合のさまざまな入出力シナリオを見てみましょう −入力 −Arr={12,67,99,76,32}; 出力 −配列内の最大値: 99 説明 &mi

5月25日のニュースによると、中国東方航空は性能説明会でC919旅客機の最新の進捗状況を明らかにした。同社によると、COMACと締結したC919購入契約は2021年3月に正式に発効し、最初のC919航空機は2022年末までに引き渡される予定だという。近く正式に実運用が開始される見通しだ。中国東方航空は上海をC919の商業運航の主拠点とし、2022年と2023年に計5機のC919旅客機を導入する計画だ。同社は、今後の導入計画については、運行実態や路線網計画を踏まえて決定するとしている。編集者の理解によれば、C919は世界で完全に独立した知的財産権を有する中国の新世代の単通路本線旅客機であり、国際的に認められた耐空基準に準拠している。すべき

数値をさまざまな形式で表示することは、学習における基本的なコーディング問題の 1 つです。条件文やループ文などのさまざまなコーディング概念。アスタリスクなどの特殊文字を使用して三角形や四角形を印刷するさまざまなプログラムがあります。この記事では、C++ の正方形と同じように、数値をスパイラル形式で出力します。行数 n を入力として受け取り、左上隅から開始して右、次に下、次に左、次に上、そして再び右、というように移動します。数字付きスパイラル パターン 123456724252627282982340414243309223948494431102138474645321120373635343312191817161514

C の void は、空の型、つまり特定の型を持たないデータを表すために使用される特別なキーワードです。 C言語ではvoidは主に以下の3つの場面で使われます。関数の戻り値の型は void です。C 言語では、関数は int、float、char などのさまざまな戻り値の型を持つことができます。ただし、関数が値を返さない場合は、戻り値の型を void に設定できます。これは、関数が実行された後、特定の値を返さないことを意味します。例: voidhelloWorld()

プログラミング言語の人気を測るベンチマークの 1 つである TIOBE プログラミング コミュニティ インデックスによると、世界中のエンジニア、コース、ベンダー、検索エンジンからデータを収集することによって評価されています。先日、2024年1月のTIOBE Indexが発表され、2023年の公式プログラミング言語ランキングが発表され、C#がTIOBE 2023 Programming Language of the Yearを受賞し、23年ぶりにC#がこの栄誉を獲得しました。 TIOBE の公式プレスリリースによると、C# は 20 年以上トップ 10 内にランクインしていましたが、現在では主要 4 言語に追いつき、1 年間で最大の成長率 (+1.43%) を示したプログラミング言語となっています。この賞を受賞するのは当然のことです。 2 位は Scratch (+0.83%) と Fortran (+0)
