問題タブ [resource-leak]
For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.
.net - .NET リソース リークの落とし穴
開発者が .NET での意図しないリソース リークに巻き込まれる方法はいくつかあります。一か所に集めておくと便利だと思いました。
項目ごとに 1 つの回答を追加してください。最高のものが投票されます :)
windows - KillTimer は必要ですか?
私はSetTimer
API を使用していますが、次のようなコードがたくさんあります。
呼び出すKillTimer
必要がありますか? そうしないと、システムはプロセスの終了時にリソースを自動的に解放しますか? 呼び出しを忘れるとKillTimer
リソース リークが発生しますか?
タイマーが必要ない場合は、によって破棄できることを理解していますKillTimer
。しかし、手動で破棄する必要がありますか?
windows - ハンドルはどこに割り当てられましたか?
WinDbg を使用して、ハンドルの割り当てにつながるコールスタックを知ることができるかどうか疑問に思っています。
例えば:
このサンプルをビルドして WinDbg で起動すると、次の行の上のサンプルで、ハンドルを割り当てたコールスタックを取得できます。
コマンドをいじっています!handle
が、これまでのところ進歩はありません。
これは、リーク分析を処理するのに適しています。私は認識し!htrace -enable
て!htrace -diff
いますが、これは別の使用シナリオです (何らかの方法で組み合わせる方法や他の使用ベクトルがない限り、情報を提供してください)。
com - COM:Release を呼び出さずに CoUninitialize を呼び出すことはできますか?
私は疑問を持っています。COM を初期化し、CoCreateInstance を実行して、いくつかのインターフェイスを使用します。Release を呼び出さずに CoUninitialize を呼び出すことはできますか? メモリ/リソースリークが発生しますか?
前もって感謝します、-マニ。
java - java.lang.ThreadLocal が ThreadLocal ではなく Thread のマップであるのはなぜですか?
素朴に、私は ThreadLocal が値型への Thread の WeakHashMap のようなものであると予想していました。そのため、 ThreadLocal の値が実際には Thread のマップに保存されていることを知ったとき、私は少し戸惑いました。なぜそのようにされたのですか?値が ThreadLocal 自体に保存されている場合、ThreadLocal に関連するリソース リークは発生しないと思います。
明確化:私は次のようなことを考えていました
私が見る限り、これは、値が何らかの形で ThreadLocal 自体を強く参照している場合、スレッドが死ぬまで ThreadLocal も残りの値もガベージコレクションされないという奇妙な問題を防ぎます。(おそらく、これの最も悪質な形式は、値が参照するクラスの静的変数が ThreadLocal である場合に発生します。オブジェクトもそのクラスも収集できないため、アプリケーション サーバーの再デプロイで大きなリソース リークが発生します。)
delphi - EOutOfResourcesを追い詰める
質問:
実行中のアプリケーションでリークするリソースの種類のリストを取得する簡単な方法はありますか?アプリケーションに接続してIOW?
memproofでそれができることは知っていますが、速度が非常に遅くなるため、アプリケーションは1分も持続しません。ほとんどのタスクマネージャーのいいねは番号を表示できますが、タイプは表示できません。
チェック自体が壊滅的である(アプリプロセスを停止する)ことは問題ではありません。近づいているかどうかをタスクマネージャーでチェックできるからです(または少なくとも私は願っています)
リソースリークハンティング(メモリではない)に関するその他の洞察も歓迎します。
バックグラウンド:
私はDelphi7/2006/2009アプリ(3つすべてでコンパイル)を持っていて、約数週間後におかしな動作を開始します。ただし、実行する場所の1つでのみ、他のいくつかのシステムでは、電源が切れるまで実行されます。
問題を絞り込むために、いくつかのデバッグコードを挿入しようとしました。そして、ファイルの保存時に例外がEOutofResourcesであることがわかりました。(ファイルの保存は1日に何千回も発生する可能性があります)。
私はメモリリークを(fastmmで)推論しようとしましたが、データフローが非常に高いため(ギガビット産業用カメラから60MByte / s)、fastmmでのみ「忍び寄る」メモリリークを除外できます。それが起こる頃の記憶。何か問題が発生した場合、アプリは30分以内にメモリをいっぱいにします。
主な容疑者は、何らかのエラーとTMetafiles(これらのファイルにストリーミングされる)に何らかの形で残されたファイルハンドルです。マイナーな容疑者はVST、popupmenu、tframesです
更新:
もう1つの考えられるヒント:D7では2年間正常に動作しましたが、現在問題はTurbo Explorer(D2009に変換されていない安定したプロジェクトに使用しています)にあります。
Paul-Jan:それは週に一度だけ起こるので(そしてそれは夜に起こる可能性があります)、情報の取得は遅いです。それが私がこの質問をする理由です、私が木曜日にそこにいるときのためにものを組み合わせる必要があります。要するに:いいえ、100%確実かどうかはわかりません。Systemtoolsコレクション全体を持ってきて、何かを見つけることができるかどうかを確認するつもりです(それから、それは数日間実行されるためです)。開いているファイルが表示される可能性もあります。(たぶん、いくつかのmingw lsofを見つけて、それをスケジュールする必要があります)
しかし、アプリはGUIアクションをほとんど認識しません(マシンビジョン検査アプリです)。ただし、画面の更新+/- 15/sはtbitmapstretchdraw+ tmetafileですが、ディスク(TFileStream)ハンドルに保存するときにこのエラーが発生する可能性があります。疲れ果てた。ただし、同じストリームで、TMetafileもsavetostreamedされます。これは、後のアプリにはもう存在しないものであり、数か月から実行できます。
- - - - - - - - - - アップデート
私は検索し、検索し、検索し、invitroで問題を2、3回再現することができました。問題は、memusageが+/- 256MB(システムには2GB)、ユーザーオブジェクト200、gdiオブジェクト500、予想よりも開いているファイルが1つではない場合に発生しました。
これは本当に例外ではありません。おそらくフレームの親を変更したために、少量のハンドルがリークしていることに気付きましたが(VCL内の何かがHPaletteをリークしているようです)、主な原因は別の問題であると思われます。TMetafileを再利用し、その間に.clearします。メタファイルをクリアしても、リソースのサイズは実際には(常に?)変更されないと思います。最終的には、tmetafileのプール全体の各メタファイルが最大サイズになります。20〜40以上のtmetafile(それぞれ数100ksになる可能性があります)を使用すると、デスクトップにヒットします。ヒープ制限。
それは理論ですが、お客様のデスクトップ制限を10MBに設定して確認しようと思いますが、変更がないか確認するまでに数週間かかります。この理論は、このマシンが特別である理由も確認しています(このマシンには、平均してわずかに大きいメタファイルがある可能性があります)。場合によっては、プール内のtmetafileを解放して再作成することも役立つ場合があります。
幸いなことに、これらすべての問題(tmetafileと親の変更の両方)は、新しい世代のアプリですでに設計されています。
特別な状況(およびテストウィンドウが非常に限られているという事実)のため、これはしばらくの間ですが、今のところ例としてデスクトップヒープを受け入れることにしました(GDILeaksのものも多少役に立ちましたが)。
監査でスレッドでのGDIタイプの使用が明らかになったもう1つのこと(ただし、(他の方法で使用または接続されていない)tmetafileのみをストリームに保存します。
-------------アップデート2。
デスクトップの制限を増やすと、問題が発生するまでの時間がわずかに増えるように見えました。
残念ながら、マシンが問題のない新しいバージョンのフレームワークに更新されたため、これについてこれ以上フォローアップすることはできません。
要約すると、古いフレームワークから新しいフレームワークへの3つの主要な変更が何であったかを述べることしかできません。
- フレームの親を変更して画面を変更することはなくなりました。現在、非表示にして表示するフォームを使用しています。これが原因で非常にまれなクラッシュや例外(クリックするとクリックされる可能性があります)も発生したため、これを変更しました。クラッシュはすべてGUIの操作中に発生しましたが、主な問題のように自発的に発生したわけではありません。
- クラッシュが発生したルーチンはTMetafileを処理しました。TMetafileは設計されており、より単純な独自の形式に置き換えられています。(基本的にOpengl頂点を持つ配列)
- 描画は、tmetafileオーバーレイstrechdrawedがその上にあるtbitmapでは発生しなくなりましたが、OpenGLを使用しています。
もちろん、上記の部分の書き直しで変更され、非常に厄介な詳細のバグを修正したものもあります。上記のシステムを可能な限り分析したので、それは非常に悪いものでなければなりません。
プライベートメールでの議論の後、 2012年11月に更新:振り返ってみると、次のステップはメタファイルオブジェクトにカウンターを追加し、x * 1000回程度使用するたびにそれらを再インスタンス化して、何かが変わるかどうかを確認することでした。同様の問題が発生した場合は、動的に割り当てられた長寿命のリソースを定期的に破棄して再初期化できるかどうかを確認してください。
c# - ManualResetEventでClose()を呼び出す必要がありますか?
私は.NETThreadingを読んでいて、 ManualResetEventを使用するいくつかのコードに取り組んでいました。私はインターネット上でたくさんのコードサンプルを見つけました。ただし、WaitHandleのドキュメントを読んだときに、次のことがわかりました。
WaitHandleはDisposeパターンを実装します。管理されていないリソースをクリーンアップするためのファイナライズと破棄の実装を参照してください。
作成したManualResetEventオブジェクトで.Close()を呼び出すサンプルはなく、pfxteamブログのRecursion and Concurrencyの記事もあります(編集-これには、私が見逃したusingブロックがあります)。これは単なる見落としの例ですか、それとも必要ありませんか?WaitHandleは「オペレーティングシステム固有のオブジェクトをカプセル化する」ため、リソースリークが発生しやすいので不思議です。
.net - DataAdapter.Fill()は、例外がスローされたときに接続を閉じますか?
レガシーアプリでADO.NET(.NET 1.1)を使用しています。DataAdapterに渡される前に接続が手動で開かれていない場合、DataAdapter.Fill()が接続を開いたり閉じたりすることを知っています。
私の質問:.Fill()が例外を引き起こした場合、接続も閉じますか?(SQL Serverに到達できないなどの理由で)。接続がリークしますか、それとも接続が閉じられていることを確認するための組み込みのFinally句がありますか?
コード例:
windows - プリンタードライバーでのリソースリークのデバッグ
プリンタ ドライバのメモリ リークをデバッグしようとしています。windbg で !heap -s を使用してヒープを分析しても増加が見られないため、単純なメモリ リークではなく、リソース リークであると確信しています。windbg を使用して他の種類のオブジェクトを監視するにはどうすればよいですか? GDI オブジェクトと開いているハンドルの数も増加していません。
メモリ リークの症状は、プライベート バイトが最大 180Mb まで増加し、印刷が開始されてランダムな問題が発生することです。
c# - 数百のカスタムUserControlが数千のUSERオブジェクトを作成します
に何百もの「アイテム」を表示するダッシュボードアプリケーションを作成していFlowLayoutPanel
ます。
各「アイテム」は、UserControl
12個のテキストボックスまたはラベルで構成されています。
私のアプリはデータベースにクエリを実行し、各レコードの「アイテム」インスタンスを作成し、ラベルとテキストボックスにデータを入力してからに追加しFlowLayoutPanel
ます。
パネルに約560個のアイテムを追加した後、タスクマネージャーの数が約7300に増えたことに気付きUSER Objects
ました。これは、私のマシン上の他のどのアプリよりもはるかに多いものです。
560 * 13(12個のラベルとUserControl自体)は7280であると考えました。そのため、すべてのオブジェクトがどこから来ているのかが突然わかりました...
Windowsがタオルを投げる前に10,000USERオブジェクトの制限があることを知って、私はこれらの「アイテム」をに描画するより良い方法を見つけようとしていFlowLayoutPanel
ます。
これまでの私の考えは次のとおりです。
多くのラベルの代わりに、を使用
graphics.DrawText
して「アイテム」をユーザーが描画します。これが13ではなくDrawImage
1アイテム=1を意味することを願っています。USER Object
「アイテム」のインスタンスを1つ作成し、レコードごとにインスタンスにデータを入力し、
Control.DrawToBitmap()
メソッドを使用して画像を取得してから、FlowLayoutPanel
(または同様の)で使用します。
だから...誰か他に何か提案はありますか?
PSこれはズーム可能なインターフェイスなので、すべてのアイテムを一度に表示する必要があるため、「ページング」はすでに除外しています。