GC.Collect()を使用することの何が問題になっていますか?


103

私はこの機能を使用することの深刻な影響を理解しています(または少なくともそれが私が思うことです)が、なぜそれが、立派なプログラマーがこれまで使用しないこれらの事柄の1つになっているのか、知らない人であっても理解できませんそれが何のためにあるのか。

ユーザーが何をしているかによってメモリ使用量が極端に異なるアプリケーションを開発しているとしましょう。アプリケーションのライフサイクルは、編集とリアルタイム処理の2つの主要な段階に分けることができます。編集の段階で、何十億、または何兆ものオブジェクトが作成されたとします。それらのいくつかは小さく、いくつかはそうでない、いくつかはファイナライザを持っているかもしれないし、いくつかは持っていないかもしれません、そしてそれらの寿命が非常に数ミリ秒から長い時間まで変化すると仮定します。次に、ユーザーはリアルタイムステージに切り替えることを決定します。この時点で、パフォーマンスが基本的な役割を果たしており、プログラムのフローのわずかな変更が壊滅的な結果をもたらす可能性があると想定します。オブジェクトの作成は、オブジェクトプールなどを使用することで可能な限り最小限に抑えられますが、GCは予期せずにチャイムし、すべてを捨てて誰かが死にます。

質問:この場合、第2ステージに入る前にGC.Collect()を呼び出すのは賢明ではないでしょうか。

結局のところ、これら2つの段階は互いに時間的に重複することは決してなく、GCが収集できたすべての最適化と統計はここではほとんど役に立ちません...

注:一部の方が指摘したように、.NETはこのようなアプリケーションに最適なプラットフォームではないかもしれませんが、それはこの質問の範囲を超えています。その目的は、GC.Collect()呼び出しがアプリケーションの全体的な動作/パフォーマンスを改善できるかどうかを明確にすることです。あなたがそのようなことを行う状況は非常にまれであることに私たちは皆同意しますが、GCはほとんどの場合、推測を試み、それを完全にうまく行いますが、それはまだ推測についてです。

ありがとう。


24
「プログラムのフローのわずかな変更が致命的な結果をもたらす可能性があります...誰かが死ぬ可能性があります」-C#.NETがあなたの目的に対して十分に確定的であると確信していますか?
スティーブジェソップ

4
Windowsも.NETもリアルタイムプラットフォームではないため、少なくとも人命を危険にさらすほどのパフォーマンス指標は保証できません。私はあなたが誇張であるか不注意であるかのどちらかでonebyoneに同意します。
セルジオアコスタ

3
「立派なプログラマーが決して使用しないこれらのことの1つ、それが何のためにあるのかさえ知らない人々でさえ」のLOL!なぜかわからないものを使うプログラマーは、私の本ではほとんど尊敬されません。:)
The Dag

回答:


87

リコのブログから...

ルール#1

しないでください。

これは本当に最も重要なルールです。GC.Collect()のほとんどの使用法は悪い考えであり、元の投稿で少し詳しく説明したので、ここではそのすべてを繰り返すことはしません。それでは次に進みましょう...

ルール#2

繰り返し発生しないイベントが発生し、このイベントが原因で多くの古いオブジェクトが停止する可能性が非常に高い場合は、GC.Collect()の呼び出しを検討してください。

この典型的な例は、クライアントアプリケーションを作成していて、大量のデータが関連付けられている非常に大きく複雑なフォームを表示する場合です。ユーザーがこのフォームを操作しただけで、XMLドキュメントや大きなDataSetなどの大きなオブジェクトが作成される可能性があります。フォームを閉じると、これらのオブジェクトは無効になるため、GC.Collect()はそれらに関連付けられたメモリを解放します...

したがって、この状況はルール#2に該当する可能性があるように思われます。多くの古いオブジェクトが停止した瞬間があり、それが再発しないことを知っています。ただし、リコの別れの言葉を忘れないでください。

ルール#1は強力な証拠なしにルール#2に勝るはずです。

測定、測定、測定。


9
これは古いものだと思います。何をしているのかがわかっていて、それをいつ、どのように行うのか、そして副作用を知っていれば、本当に悪いことや危険なことはありません。絶対にしないでください、xxxxを使用することは、お粗末なプログラマーから世界を守るためにそこに置かれます:D
ホルヘコルドバ


GC.Collectの使用は良い習慣ではありません。しかし、実際の原因を知らなくても問題をすばやく解決できる場合もあります。それは醜いです、しかし私は知っています、しかしそれはうまくいきます、そして特に問題の根本的な原因を理解する時間があまりなく、あなたの上司があなたの後ろに立っているときは特に悪いアプローチではないようです...あなたは知っています。
Silent Sojourner 2018年

58

プロダクションコードでGC.Collect()を呼び出す場合、基本的には、GCの作成者よりも知っていることを宣言しています。それは事実かもしれません。ただし、通常はそうではないため、お勧めしません。


3
それは本当ですが、すべての開発に当てはまる仮定を立てられるかどうかはわかりません。
MasterMastic 2012

2
@ケンいいえ、できません。しかし、あなたはそうするためにより良い立場にありますか?または、特定のハードウェア、特定のOSバージョンなどを想定してコードを記述しますか?これでは痛み/ゲイン比が高すぎます。
Dag

2
@TheDag IMOもちろんです。私がメモリを解放しているとき、それを処理するのはOSの仕事なので、ハードウェアは本当に気にしません。また、プログラミングしているすべてのインターフェイスに共通のインターフェイスを持っているので、OSも気にしません。(たとえば、それがWindows、Mac、またはLinuxであるかどうかは関係ありません。C/ C ++でメモリを割り当てたり解放したりすると、malloc / deallocは新規または削除されます)。私はいつも間違っている可能性があるので、自由に修正してください。
MasterMastic 2013年

@MasterMastic mallocには非常にシンプルなインターフェースしかないため、実装はさまざまな問題に対応できます。それはすべて、解決しようとしている問題の種類によって異なります。malloc「十分」であれば、バッファプーリングは不要でしょうか。C / C ++開発である完全なあなたがよく知っている(そして時には、あなたが本当にやり)ので、あなたは第二推測OS /ランタイム/ライブラリにしてみてください例。多くのパフォーマンス重視のアプリケーションは、システム/ランタイムアロケーターの使用を完全に回避しています。起動時にすべてのメモリを事前に割り当てるために使用されるゲーム(一定サイズの配列など)。
Luaan 2017

24

では、.NETのMS WordやMS ExcelなどのCOMオブジェクトを使用している場合はどうでしょうか。GC.CollectCOMオブジェクトを解放した後に呼び出しを行わないと、WordまたはExcelアプリケーションのインスタンスがまだ存在していることがわかりました。

実際に使用するコードは次のとおりです。

Utils.ReleaseCOMObject(objExcel)

' Call the Garbage Collector twice. The GC needs to be called twice in order to get the
' Finalizers called - the first time in, it simply makes a list of what is to be finalized,
' the second time in, it actually does the finalizing. Only then will the object do its 
' automatic ReleaseComObject. Note: Calling the GC is a time-consuming process, 
' but one that may be necessary when automating Excel because it is the only way to 
' release all the Excel COM objects referenced indirectly.
' Ref: http://www.informit.com/articles/article.aspx?p=1346865&seqNum=5
' Ref: http://support.microsoft.com/default.aspx?scid=KB;EN-US;q317109
GC.Collect()
GC.WaitForPendingFinalizers()
GC.Collect()
GC.WaitForPendingFinalizers()

それでは、ガベージコレクタの使い方が間違っているのでしょうか。もしそうなら、相互運用オブジェクトをどのようにして死なせるのですか?また、このように使用することを意図していない場合、GCCollectメソッドはなぜPublicですか?


3
これは、StackOverflowというすばらしい新しい質問になります。つまり、GCを呼び出さずにCOMインスタンスを根絶する方法。管理されていない循環参照については特に。これは、VB6 OutlookアドインをC#にアップグレードすることを警戒させた課題の1つです。(VB側でコーディングパターンとテストケースを開発するために多くの作業を行い、COM参照が不要になったときに確定的な方法で強制終了されることを保証しました)。
rkagerer

2
これがCOMオブジェクト全般に当てはまる場合、おそらくこれは有効なシナリオです。しかし、最初から問題は、インタラクティブデスクトップ用に設計されたクライアントアプリケーションをCOMサーバーとして使用している可能性が高いと思います。MSDNナレッジベース:「Microsoftは現在、無人の非対話型クライアントアプリケーションまたはコンポーネント(ASP、ASP.NET、DCOM、およびNTサービスを含む)からのMicrosoft Officeアプリケーションの自動化を推奨しておらず、サポートもしていません。この環境でOfficeを実行すると、動作が不安定になったり、デッドロックが発生する可能性があります。」
Dag

2
@TheDag-Microsoftは推奨しないかもしれませんが、私たちの多くは古いVB6コードをOffice相互運用機能で.Net Windowsアプリに移植する必要がありました。大きなVB6から.Netへの変換プロジェクトで、目に見えないぶら下がっているすべての参照を最終的に取り除くまで、数か月の作業を費やしました。しかし、逆の割り当て順序で解放することを学び、コレクションを含むすべての単一のcomオブジェクトへのローカル参照を保持することは役に立ちました。
Dib

15

まあ、GCは私が愛/憎しみの関係を持っているものの1つです。私たちは過去に VistaDBを通じてそれ壊し、それについてブログを書いています。彼らはそれを修正しましたが、このようなものから修正を得るには長い時間がかかります。

GCは複雑であり、1つのサイズですべてのアプローチに対応することは、このような大きなものを引き抜くのが非常に困難です。MSはかなりうまく機能していますが、GCをだましてしまう可能性もあります。

一般にCollect、大量のメモリをダンプしたという事実を知らない限り、を追加しないでください。GCがクリーンアップしないと、中年の危機に陥ります。

一連の悪いGC.Collectステートメントでマシン全体を台無しにすることができます。collectステートメントの必要性は、ほとんどの場合、より大きな根本的なエラーを示しています。メモリリークは通常、参照とそれらがどのように機能するかについての理解の欠如に関係しています。または、IDisposableそれを必要としないonオブジェクトを使用して、GCにはるかに高い負荷をかけます。

システムパフォーマンスカウンターを通じて、GCに費やされた時間の割合を注意深く監視します。GCでアプリがその時間の20%以上を使用している場合、オブジェクト管理に重大な問題(または異常な使用パターン)があります。アプリ全体の速度が向上するため、GCが費やす時間を常に最小限に抑える必要があります。

サーバーとワークステーションではGCが異なることに注意することも重要です。私は、両方をテストしていない(または、それらが2つであることを認識していない)人々の問題を追跡するのが難しい小さな問題をいくつか見ました。

そして、私の回答をできるだけ完全にするために、そのプラットフォームもターゲットにしている場合は、Monoでもテストする必要があります。まったく異なる実装であるため、MSの実装とはまったく異なる問題が発生する可能性があります。


犯人はしばしば出来事です。インスタンスメソッドがイベントハンドラーとして使用される場合は常に、イベントのパブリッシャーはイベントデリゲートを介してサブスクライバーへの参照を持ちます。これによる問題を回避する唯一の「簡単な」方法は、サブスクライバーと同じくらい長く存続するパブリッシャーのみを使用することです(たとえば、含まれているフォームによって処理されるイベントをパブリッシュするTextBoxは問題ではありません。テキストボックスは想定されていないため)フォームの外に住んでいます)。問題のシナリオ例:シングルトンモデル、モデルイベントを処理する一時ビュー。
ダグ2013年

5
どうすればマシン全体を台無しにすることができますか?
アダムR.グレイ

13

これが役立つ状況もありますが、一般的には避ける必要があります。GOTOと比較したり、モペットに乗ったりすることができます。必要なときにそれを行いますが、友達には知らせません。


12

私の経験から、本番コードでGC.Collect()を呼び出すことはお勧めできません。デバッグでは、はい、潜在的なメモリリークを明確にするのに役立つ利点があります。私の根本的な理由は、GCがプログラマーによってはるかに賢く書かれて最適化されていることだと思います。どこかに。あなたの状況では、あなたが実際にメモリの問題を抱えているように聞こえません、あなたがコレクションがあなたのプロセスにもたらす不安定性を心配しているというだけです。まだ使用中のオブジェクトをクリーンアップしないこと、および需要の増加と減少の両方に非常に迅速に適応することを考えると、心配する必要はないと思います。


10

GC.Collect()を呼び出す最大の理由の1つは、説明したような大量のゴミを作成する重要なイベントを実行した直後です。ここでは、GC.Collect()を呼び出すことをお勧めします。そうしないと、GCはそれが「1回限り」のイベントであると理解できない場合があります。

もちろん、それをプロファイリングして、自分の目で確かめてください。


9

まあ、明らかに、非リアルタイムガベージコレクションのある言語でリアルタイム要件のあるコードを書くべきではありません。

明確に定義されたステージの場合、ガベージコレクターのトリガーに問題はありません。しかし、このケースは非常にまれです。問題は、多くの開発者がこれを使用してカーゴカルトスタイルのペーパーオーバー問題を試行し、無差別に追加するとパフォーマンスの問題が発生することです。


そうだね。ただし、「ガベージコレクションに適さないオブジェクトであるはずのオブジェクト」というエラー状態を検出できる自動テストは価値があります。これは、ファクトリロジック、デストラクタロジック、およびGC.Collectの組み合わせによって実現される可能性があります。たとえば、EntityクラスにはIObjectTrackerプロパティがあり、通常はnullですが、テスト目的のエンティティファクトリによって割り当てられます。また、ファクトリーはオブジェクトの誕生をトラッカーに通知しますが、デストラクタは(存在する場合)死を通知します。「デストラクタがすべてのガベージコレクション可能なオブジェクトに対して実行された」ことがわかる場合は、トラッカーの状態をチェックしてリークを検出できます。
Dag

7

GC.Collect()を呼び出すと、CLRはスタックウォークを実行して、参照をチェックすることによって各オブジェクトを本当に解放できるかどうかを確認します。オブジェクトの数が多い場合、これはスケーラビリティに影響を及ぼし、ガベージコレクションを頻繁にトリガーすることも知られています。CLRを信頼し、必要に応じてガベージコレクター自体を実行させます。


2
スタックウォークを引き起こすだけでなく、GC スタックウォークできるように、アプリケーションのメインスレッド(およびそれによって作成された子スレッド)が凍結されます。アプリがGCに費やす時間が長いほど、アプリの凍結に費やす時間が長くなります。
スコットドーマン、

3
アプリ/ GCが不要なものをスローしていたため、パフォーマンスの低下よりもメモリ不足の例外によるアプリのクラッシュの方が心配です。Microsoftが最初にゴミを捨てずにOOM例外を投げているように見える理由を誰かが知っていますか?または私は必ず私が「自動的に」「彼らがすることになっている道を。」起こって物事のあらゆる信仰を持っていないんだけどOOM例外をスローする前に、このステップが試みられていないよう理由の少なくとも説明- (このOBVIOUSステップなし
ワンダーバード

6

実際には、GC.Collectを呼び出すのは非常に悪い習慣だとは思いません。
それが必要な場合もあります。たとえば、私はスレッドを実行し、データベースの異なるテーブルを開き、BLOBフィールドの内容を一時ファイルに抽出し、ファイルを暗号化してから、ファイルをバイナリストリームに読み取ってBLOBに戻すフォームを持っています別のテーブルのフィールド。

全体の操作にはかなりのメモリが必要であり、テーブルの行数やファイルコンテンツのサイズについては不明です。

私はOutofMemory Exceptionを頻繁に取得していましたが、カウンター変数に基づいて定期的にGC.Collectを実行するのが賢明だと思いました。カウンターをインクリメントし、指定されたレベルに達すると、GCが呼び出され、形成された可能性のあるガベージを収集し、予期しないメモリリークによって失われたメモリを取り戻します。

この後、私はそれが少なくとも例外なくうまく機能していると思います!!!
私は次のように呼びます:

var obj = /* object utilizing the memory, in my case Form itself */
GC.Collect(GC.GetGeneration(obj ,GCCollectionMode.Optimized).

5

.netでは、ガベージコレクションの実行に必要な時間は、ガベージではないものの量よりも、ガベージではないものの量に強く関係しています。実際、オブジェクトがFinalize(明示的に、またはC#デストラクタを介して)オーバーライドする場合、のターゲットであるWeakReference場合、ラージオブジェクトヒープに配置される場合、または他のgc関連の方法で特別な場合を除いて、オブジェクトが配置されるメモリを識別する唯一のものはオブジェクトであるのは、それへのルート化された参照の存在です。それ以外の場合、GCの操作は、建物からすべての価値のあるものを取り出し、建物をダイナマイトし、古い建物の敷地に新しい建物を建設し、それにすべての貴重なアイテムを入れることに似ています。建物のダイナマイトに必要な労力は、建物内のゴミの量とは完全に無関係です。

その結果、呼び出しGC.Collectは、システムが実行する必要がある全体的な作業量を増加させる傾向があります。次のコレクションの発生を遅らせますが、おそらく、次のコレクションが発生したときに必要だったのと同じだけの作業をすぐに実行します。次のコレクションが発生していたときの時点で、収集に費やした時間の合計はしていたとほぼ同じだっただろうGC.Collectと呼ばれていないが、システムは、いくつかのゴミを蓄積してきただろう、後続のコレクションが早く持っていたより必要とされることが原因GC.Collectではありません呼ばれました。

私がGC.Collect本当に役立つと思うのは、コードのメモリ使用量を測定する必要があるときです(メモリ使用量の数値はコレクションの後でのみ意味があるため)、またはいくつかのアルゴリズムのどちらがより良いかをプロファイルする(GC.Collect()を呼び出す)いくつかのコードのそれぞれを実行する前に、一貫したベースライン状態を確保するのに役立ちます)。GCが知らないことは他にもいくつかありますが、シングルスレッドのプログラムを作成していない限り、1 GC.Collectつのスレッドのデータ構造を支援する呼び出しが「中年の危機」を回避できることを知る方法はありません。「他のスレッドのデータに、そうでなければ回避されていたであろう「中期の危機」が発生することはありません。


5

ループでのイメージの作成-disposeを呼び出しても、メモリは回復されません。毎回ガベージコレクト。写真処理アプリのメモリが1.7GBから24MBになり、パフォーマンスは優れています。

GC.Collectを呼び出す必要がある時間は絶対にあります。


2
呼び出しDisposeはマネージメモリ解放するためのものではありません。.NETのメモリモデルがどのように機能するかを知らないようです。
Andrew Barber、

4

ガベージコレクターがガベージを収集せず、メモリを解放するという同様の問題がありました。

私たちのプログラムでは、OpenXMLを使用して適度なサイズのExcelスプレッドシートをいくつか処理していました。スプレッドシートには、5行から10行の「シート」が含まれ、14行で約1000行が含まれていました。

32ビット環境(x86)のプログラムは、「メモリ不足」エラーでクラッシュしました。x64環境で実行することはできましたが、より優れたソリューションが必要でした。

見つけました。

以下は、破棄されたオブジェクトからメモリを解放するためにガベージコレクターを明示的に呼び出すときに機能しないものと機能したもののいくつかの簡略化されたコードフラグメントです。

サブルーチン内からGCを呼び出しても機能しませんでした。記憶は取り戻されなかった...

For Each Sheet in Spreadsheets
    ProcessSheet(FileName,sheet)
Next

Private Sub ProcessSheet(ByVal Filename as string, ByVal Sheet as string)
    ' open the spreadsheet 
    Using SLDoc as SLDocument = New SLDocument(Filename, Sheet)
        ' do some work....
        SLDoc.Save
    End Using
    GC.Collect()
    GC.WaitForPendingFinalizers()
    GC.Collect()
    GC.WaitForPendingFinalizers()
End Sub

GC呼び出しをサブルーチンのスコープ外に移動することにより、ガベージが収集され、メモリが解放されました。

For Each Sheet in Spreadsheets
    ProcessSheet(FileName,sheet)
    GC.Collect()
    GC.WaitForPendingFinalizers()
    GC.Collect()
    GC.WaitForPendingFinalizers()
Next

Private Sub ProcessSheet(ByVal Filename as string, ByVal Sheet as string)
    ' open the spreadsheet 
    Using SLDoc as SLDocument = New SLDocument(Filename, Sheet)
        ' do some work....
        SLDoc.Save
    End Using
End Sub

これが、.NETガベージコレクションでイライラしている他の人が、への呼び出しを無視しているように見える場合に役立つことを願っていますGC.Collect()

ポールスミス


4

コレクションを明示的に呼び出すことに問題はありません。一部の人々は、それがベンダーによって提供されるサービスである場合、それを疑わないでくださいと本当に信じたいだけです。ああ、そしてそれらのランダムなものがすべて、インタラクティブなアプリケーションの間違った瞬間にフリーズしますか?次のバージョンはそれをより良くするでしょう!

バックグラウンドプロセスでメモリ操作を処理できるようにするということは、自分で処理する必要がないことを意味します。しかし、これは、すべての状況下で自分自身で対処しないことが最善であることを論理的に意味するものではありません。GCはほとんどの場合に最適化されています。ただし、これは、すべてのケースで最適化されていることを論理的に意味しているわけではありません。

決定的な答えで「最良のソートアルゴリズムはどれですか」などの未解決の質問に答えたことがありますか?その場合は、GCに触れないでください。条件を要求した、または「この場合は」タイプの回答を提供した場合は、GCといつそれをアクティブ化するかについて学ぶことができます。

お奨めは、私がChromeとFirefoxでアプリケーションのフリーズを起こして、私を驚かせてしまったことです。それでも、場合によっては、メモリが妨げられずに成長します-ガベージコレクターを呼び出すことを学んだだけなら-またはボタンをクリックして、ページのテキストを読み始めると、ページにアクセスできるので、次の20分間フリーズしなくなります。


2

シナリオは正しいと思いますが、APIについてはわかりません。

Microsoftは、そのような場合、GCにコレクションをすぐに実行するヒントとしてメモリプレッシャー追加する必要があると述べています。


2
興味深いですが、ドキュメントでは、「小さな管理対象オブジェクトが大量のUN管理対象メモリを割り当てる」ときにAddMemoryPressureを使用する必要があると述べています。(強調鉱山)
ロバート・ポールソン

2

どうしたの?ガベージコレクターとメモリアロケーターを2番目に推測しているという事実は、それらの間で、実行時のアプリケーションの実際のメモリ使用量よりもはるかに優れたアイデアを持っています。


1
ガベージコレクタのヒューリスティックな性質と、この機能が外部の世界に公開されたという事実は、必要な場所で使用した場合に役立つものだと考えさせられます。問題はそれを使用するのではなく、それをどのように、どこで、いつ使用するかを知ることです。
トラップ

GCは言うまでもなく、他のすべてアプリケーションとそれらのメモリの必要性についてのより良い知識です。GCはOSとメモリをネゴシエートするため、利用可能な物理メモリと、管理対象と管理対象外の両方のマシン上の他のすべてのプロセスの影響を受けます。GCが「ケースバイケース」の基準で「いつ収集するのが適切な時期か」を本当に知っているとは思えませんが、全体としては、単一のアプリケーションよりも優れた戦略を持つ可能性が高くなります。;)
Dag

2

GC.Collect()を呼び出したいという願望は、通常、どこかで行った間違いを隠そうとしています!

不要になったものを処分するのを忘れた場所を見つけた方がよいでしょう。


5
それはおそらく一般化です
MickyD 2012年

1

つまり、アプリケーションのプロファイルを作成し、これらの追加のコレクションがどのように影響するかを確認できます。あなたがプロファイリングするつもりでない限り、私はそれから離れることをお勧めします。GCはそれ自体を処理するように設計されており、ランタイムが進化するにつれて効率が向上する可能性があります。作業をつぶして、これらの改善点を活用できない可能性のあるコードの束がぶらぶらしたくない。foreachの代わりにforeachを使用することについても同様の議論があります。つまり、カバーの下での将来の改善をforeachに追加でき、コードを変更して利用する必要がないということです。


1

.NET Framework自体は、リアルタイム環境で実行するようには設計されていません。本当にリアルタイム処理が必要な場合は、.NETベースではない組み込みリアルタイム言語を使用するか、Windows CEデバイスで実行されている.NET Compact Frameworkを使用します。


WASがリアルタイム環境用に設計した.Net Micro Frameworkを使用している可能性があります。
TraumaPony 2008

@TraumaPony:このページの下部にあるチャートを確認してくださいmsdn.microsoft.com/en-us/embedded/bb278106.aspx:明らかに、Micro Frameworkはリアルタイム環境用に設計されていません。ただし、組み込み環境(WinCEなど)用に設計されていますが、電力要件は低くなっています。
スコット・ドーマン

1

最悪の場合、プログラムが少しフリーズします。それでよければ、それをやってください。通常は、主にユーザーの操作が必要なシッククライアントやウェブアプリでは必要ありません。

実行時間の長いスレッドを含むプログラム、またはバッチプログラムでは、オブジェクトを適切に破棄している場合でも、OutOfMemory例外が発生することがあります。覚えているのは、基幹業務のデータベーストランザクション処理でした。もう1つは、シッククライアントアプリのバックグラウンドスレッドのインデックス作成ルーチンです。

どちらの場合も、結果は単純でした。GC.Collectがなく、一貫してメモリ不足です。GC.Collect、完璧なパフォーマンス。

メモリの問題を解決するために何度か試してみましたが、役に立ちませんでした。取り出しました。

要するに、エラーが発生しない限りそれを入れないでください。入れてもメモリの問題が解決しない場合は、取り外してください。リリースモードでテストし、リンゴとリンゴを比較してください。

物事がこれでうまくいかない唯一の時は、あなたがそれについて道徳的になるときです。それは価値観の問題ではありません。多くのプログラマーが亡くなり、多くの不必要なGCで天国に直行しました。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.