静的コード分析(特にAivostoのProject Analyzer)を使用して学んだVBについて学んだことの多く。そして、それがチェックすることの1つは、すべてのオブジェクトと配列をクリアしたかどうかです。PAがそう言ったので、私はこれを盲目的に行っていました。しかし、VBがリソースを解放する方法についてもう少し知ったので、これらのことは自動的に行われるはずだと私には思えます。これはVB6より前のレガシー機能ですか、それともオブジェクトを明示的にゼロに戻し、アレイで消去を使用する必要がある理由がありますか?
5 に答える
Advanced Visual Basic6の作者であるMattCurlandは、私たちのほとんどがこれまで以上にVisual Basicについてよく知っているので、それは無駄な努力だと考えています。主にAccessDatabaseEngineを対象とするCOMデータアクセスライブラリであるDAOに関するこの引用(p110)を検討してください。
貧弱な分解コードの別の例。DAOには、正しい順序で呼び出す必要のあるCloseメソッドがあり、オブジェクトも正しい順序でリリースする必要があります(たとえば、データベースの前のレコードセット)。この単一の貧弱なオブジェクトモデルの動作は、関数の最後ですべてのローカル変数を明示的に何にも設定しない限り、VBがメモリをリークするという誤解を招きました。これは、適切に設計されたオブジェクトモデルでは完全に誤った概念です。VBは、コードから実行するよりもEnd Sub行で変数をすばやくクリアでき、参照を明示的に解放した場合でも変数をチェックします。あなたがするどんな努力も複製されます。
問題は、私が理解しているように、VB6(およびその前身)がCOMにルーツを持ち、参照カウントガベージコレクションシステムを持っているという事実に関係しています。
たとえば、サードパーティのライブラリからのオブジェクトへの参照を宣言するとします。そのオブジェクトにはCOM参照カウントがあり、これを使用して、オブジェクトを存続させ、いつ破棄するかを決定します。Nothingに設定しても破棄されませんが、オブジェクトの参照カウントがゼロに達したときに破棄されます。
現在、すべてのCOMコンポーネントがVisualBasicで記述されているわけではありません。一部はCまたはC++で書かれています。構造化例外処理は、すべての言語に存在するわけではありませんでした。そのため、エラーが発生した場合、オブジェクトの参照カウントが適切に削減されることは保証されておらず、COMオブジェクトは意図したよりも長くハングしていることがわかっていました。これは、VisualBasic自体では問題ではありませんでした。それはCOMの問題でした。(そして、ご存知かもしれませんが、.NETが参照カウントを使用しないのはそのためです。)
そのため、Visual Basicの開発者は、ルーチンを終了する前にオブジェクト参照を解放することに執着するようになりました。割り当てているコンポーネントが内部で何を作成しているのかがわからないだけです。しかし、それへの参照を解放すると、少なくともそれへの参照カウントが解放されます。それはほとんど宗教的なマントラになりました。宣言し、使用し、解放します。それはCOMのやり方でした。
確かに、Visual Basicは、スタックで宣言した変数の逆参照の方が優れているか、高速である可能性があります。しかし、くそー、私はそれらのオブジェクトがリリースされたことを明白にしたいと思います。メモリリークを追跡しようとしているときは、少しの保証が大いに役立ちます。
このAivostoWebページ(Project Analyzerの作成者から)を読んだことがありますか?
静的変数を使用している場合、変数が不要になったときに、静的変数が占有していたメモリを再利用することが重要です。動的変数の場合、手順が終了するとメモリが破棄されるため、メモリはそれほど問題にはなりません。
つまり、通常の非静的なローカル変数をクリアすることを心配する必要はありません。
私は常に良い習慣のためにそれを行います。例外が1つに該当し、オブジェクトの割り当てが解除されていない場合に例外がどうなるかはわかりません。これらをfinallyステートメントで解放し、メモリを使用していないことを確認する必要があります。そうしないと、メモリリークが発生する可能性があります。
サーバーがランダムにクラッシュし続ける単純なタイムオフトラッカーシステムの内部で問題が発生しました。それが、それ自体が自己破壊するはずのオブジェクトのメモリリークであると判断するのに数週間かかりました。私のコードは例外にスローされ、それ自体がクリーンアップされなかったため、サーバー(サーバー全体ではなく実際のWebサイト)がダウンしていました。
はい、すべてのオブジェクトを「なし」に設定し、可能な限りクリーンアップします。VB6は、クリーンアップしていないときにメモリリークが発生することで有名です。ガベージコレクションは、VB6/VBAでは標準以下でした。