問題タブ [resource-disposal]
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.
java - Javaスレッドにスレッドローカルデータベース接続を強制的に閉じる方法
スレッドローカルデータベース接続を使用する場合、スレッドが存在するときに接続を閉じる必要があります。
これは、呼び出し元のスレッドのrun()メソッドをオーバーライドできる場合にのみ実行できます。それでも素晴らしい解決策ではありません。終了時に、そのスレッドによって接続が開かれたことがあるかどうかはわかりません。
問題は実際にはもっと一般的です:スレッドが終了するときにスレッドローカルオブジェクトのファイナライズメソッドを呼び出すようにスレッドを強制する方法。
java 1.5のソースを調べたところ、スレッドローカルマップがnullに設定されていることがわかりました。これにより、最終的にガベージコレクションがfinalize()を呼び出すようになりますが、ガベージコレクターを頼りにしたくありません。
データベース接続を確実に閉じるには、次のオーバーライドが避けられないようです。
ここで、release()は、データベース接続が開かれている場合は、データベース接続を閉じます。しかし、スレッドがこのスレッドローカルを使用したことがあるかどうかはわかりません。get()がこのスレッドによって呼び出されたことがない場合は、ここでかなりの労力が無駄になります。ThreadLocal.initialValue()が呼び出され、このスレッドにマップが作成されます。
Thorbjørnのコメントによるさらなる説明と例:
java.lang.ThreadLocalは、スレッドにバインドされているオブジェクトのファクトリの一種です。このタイプには、オブジェクトのゲッターとファクトリメソッド(通常はユーザーが作成)があります。getterが呼び出されると、このスレッドによって以前に呼び出されたことがない場合にのみ、ファクトリメソッドが呼び出されます。
ThreadLocalを使用すると、開発者は、スレッドコードがサードパーティによって作成された場合でも、リソースをスレッドにバインドできます。
例: MyTypeというリソースタイプがあり、スレッドごとに1つだけにしたいとします。
usingクラスで定義します。
このクラスのローカルコンテキストで使用します。
get()は、呼び出し元のスレッドのライフサイクルで一度だけinitialValue( )を呼び出すことができます。その時点で、MyTypeのインスタンスがインスタンス化され、このスレッドにバインドされます。このスレッドによるget()の後続の呼び出しは、このオブジェクトを再度参照します。
典型的な使用例は、MyTypeがスレッドセーフでないtext / date/xmlフォーマッターである場合です。
しかし、そのようなフォーマッターは通常、解放または閉じる必要はありません。データベース接続は解放する必要があります。私はjava.lang.ThreadLocalを使用して、スレッドごとに1つのデータベース接続を確立しています。
私の見方では、java.lang.ThreadLocalはそのためにほぼ完璧です。呼び出し元のスレッドがサードパーティのアプリケーションに属している場合、リソースのクローズを保証する方法がないためです。
私はあなたの頭脳の従者が必要です:java.lang.ThreadLocalを拡張することによって、私はスレッドごとに1つのデータベース接続をバインドすることができました。これは、変更またはオーバーライドできないスレッドを含む排他的な使用法です。キャッチされない例外でスレッドが停止した場合に備えて、接続が確実に閉じられるようにしました。
通常のスレッド終了の場合、ガベージコレクターは接続を閉じます(MyTypeがfinalize()をオーバーライドするため)。実際には、それは非常に迅速に発生しますが、これは理想的ではありません。
もし私が自分のやり方を持っていたら、java.lang.ThreadLocalに別のメソッドがあったでしょう:
このメソッドがjava.lang.ThreadLocalに存在し、スレッドの終了/終了時にJVMによって呼び出された場合、それを自分でオーバーライドして、接続を閉じることができます(そして、償還者はZionに来たはずです)。
そのような方法がない場合、私は閉鎖を確認する別の方法を探しています。JVMガベージコレクションに依存しない方法。
c# - C# フォントの破棄を追跡する方法
例外の原因となっている破棄中のフォントがあり、フォントが破棄されている場所が見つかりません。印刷プレビューで処分されているような気がします。誰かがこの問題を追跡する方法を推奨できますか?
ありがとう。
java - (リソースオブジェクトの)ファイナライザーからスローをスローする方法
ファイナライザーはデストラクタではなく、ファイナライザーは役に立ちません。
私が聞いたところによると、多くのJavaリソースオブジェクトは「万が一に備えて」finalize()で処理します。
これは、バグにつながる可能性のある過度に寛容な態度のようです。
少なくとも、ファイナライズしてエラーをログに記録し(ファイナライズ時に未廃棄のリソース)、それらを標準出力に出力してから廃棄することをお勧めします。
より制限的な態度は、代わりに例外をどのように処理するかということかもしれません。このような制限のあるリソースオブジェクトを実装する必要はありませんが、その方法を知りたいと思います。
ただし、Javaでは、ファイナライザーでスローされた例外は無視されます(それ以外の場合、オブジェクトはリストに戻されて再度ファイナライズされます)。このようなものを実装する方法はありますか?おそらく、オブジェクトを作成したスレッドがまだ存在する場合はファイナライザーからの例外を与える方法(または存在しない場合は親スレッド?
また!!!!!他のgc言語(特にC#、pythonなど)は、リソースのファイナライズをどのように処理しますか(通常、リソースクラスの「万が一の処分」を実装しますか?)、ファイナライザーからスローし、他のスレッドに例外を与えます。(注:disposeメソッドを呼び出すために砂糖を使用したり、リソースを自動的に閉じるクロージャーを受け入れるメソッドを使用したりすることはあまり気にしません。ファイナライザーが果たす役割とファイナライザーからのエラー伝播に興味があります)。
delphi - Delphi アプリでのメモリ リーク。オブジェクトと文字列を適切に処分するには?
私の質問は、悪夢のようなメモリ リークのデバッグに関するものです。
私のアプリには、から派生した単純なクラスがありTObject
ます。そのクラスのすべてのオブジェクトは、から派生したクラスのコレクション/リストに格納されますTObjectList
。
使用シナリオ:
クローラーはオファーをダウンロードして解析し、オブジェクト コレクションに保存します。このアプローチは、後でオブジェクトを参照できるため、非常に便利なようです (グリッド/リストを埋める、ファイルに書き込むなど)。
問題は、メモリ リークを回避するためのオブジェクトの適切な破棄です。アプリは開始時に最大 4Mb のメモリを割り当てますが、最大 12k のオファーを処理した後、32Mb を消費します。プロセスが終了した後、適切に破棄されていないオブジェクト/変数によって引き起こされるリーク。
ReportMemoryLeaksOnShutdown
恐ろしい数字を示していますが、重要なのは-どこを見ればいいのか、どうすれば適切にデバッグできるのかわかりません。
別の例はvar MyString: string
、適切な処分が必要な変数です!! それは私にとってちょっとした洞察でした:)各プロシージャ/関数は、スコープ外の変数のガベージコレクションを自動的に管理すると思いました。
オファーのリストは、次の関数によって作成されます。
次に、これらのオファーをコレクションとして直接扱います。重要なことは、このアプリを 24 時間年中無休で実行することです。そのため、適切なリソースの処分が必須です。
- 上記のタイプのオブジェクトを適切に処分する方法は?
- オブジェクト/オブジェクト リストを管理するための他の手法を検討しますか?
- タイプの変数を適切に破棄する方法は
string
? - Delphi でのメモリ リークとの戦いに関する良い読み物を教えてください。
ありがとうございました。