2009-10-06 18 views
8

私は静的コード分析を使用してから学んだ私はVBについて学んだことの多く(特にAivostoのプロジェクトアナライザ)。それがチェックするものの1つは、すべてのオブジェクトと配列をクリアしたかどうかです。私はPAがそう言いましたので、これを盲目的にやっていました。しかし、VBがリソースを解放する方法についてもっと少し知ったので、これらのことが自動的に起こっているはずです。これはVB6以前のレガシー機能ですか?それとも、オブジェクトを何も明示的に戻さずに配列を消去する必要がある理由はありますか?はVB6/VBA(賛否/短所?)内のオブジェクトクリア/配列の解放が本当に必要です

答えて

4

問題は、私が理解しているように、VB6(およびその前身)はCOMの根源と参照カウントのガベージコレクションシステムを持っているという事実と関係しています。

を使用すると、サードパーティのライブラリからオブジェクトにreferneceを宣言すること、例えば、想像してみてください。そのオブジェクトにはCOM参照カウントがあり、COM参照カウントは、それを生き続けるために、またいつ破棄すべきかを判断するために使用されます。それをNothingに設定すると破棄されるのではなく、オブジェクトの参照カウントがゼロになったときに破棄されます。

ここで、すべてのCOMコンポーネントがVisual Basicで記述されているわけではありません。いくつかはCまたはC++で書かれています。構造化された例外処理は、すべての言語にわたって存在しませんでした。したがって、エラーが発生した場合、オブジェクトの参照カウントが適切に減少することが保証されておらず、COMオブジェクトは意図したよりも長くぶら下がることが分かっていました。これはVisual Basic自体の問題ではありませんでした。それはCOMの問題でした。 (そして、それは、.NETが参照カウントを使用しない理由であることに気付くかもしれません。)

Visual Basic開発者は、ルーチンを終了する前にオブジェクト参照を解放することに強くなったのです。あなたが割り当てているコンポーネントがボンネットの下で作成しているものが分かりません。しかし、参照を解放すると、参照カウントが解放されます。それはほとんど宗教的なマントラになった。宣言、使用、解放。それは物事を行うCOMの方法でした。

確かに、Visual Basicでは、スタック上で宣言した変数を参照解除する方が優れています。しかし、私はそれがオブジェクトがリリースされたことを明らかにしておきたい。あなたがメモリリークを追跡しようとしているとき、小さな保証は長い道のりになります。

0

は、私は常に良い練習のためにそれを行う、あなたは1に該当し、あなたのオブジェクトが割り当て解除されていない場合は、例外が行う可能性があります知っていることはありません。最終的なステートメントでそれらをリロケートし、メモリを使用していないことを確認してください。そうでなければ、メモリリークが発生する可能性があります。

私は、サーバがランダムにクラッシュしていたシンプルなタイムオフトラッカーシステムの中に問題がありました。それは、自分で自己破壊すると思われるオブジェクトのメモリリークであると判断するまでに数週間かかりました。私のコードは例外に投げ込まれていて、サーバー自体(サーバー全体ではなく実際のWebサイト)がダウンする原因となりました。

+0

興味深いことに、それはどのような種類のオブジェクトですか?それはどのような範囲ですか?トラップ可能な例外がスローされたのか、アプリがクラッシュしたのか?標準の例外がスローされると、プロシージャは終了します。たとえ例外があっても、すべてのローカル参照は自動的に破棄されます。したがって、プロシージャの外側にあるオブジェクトへの参照がない場合、そのオブジェクトが「生きている」状態に留まる原因は何ですか? – Oorang

+2

VB6/VBAでは、Try/Catch/Finallyブロックや例外はありません。 – HardCode

+0

Try/Catch/Finallyブロックはありませんが、トラップ可能な例外があります。 Err.Raiseを見てください。 – Oorang

-2

はい、Nothingにすべてのオブジェクトを設定し、できるだけ多くをクリーンアップします。 VB6はあなたのものをきれいにしないときにメモリリークを起こしたことで有名です。ガベージコレクションはVB6/VBAでサブパネルでした。これまで私たちのほとんどよりもVisual Basicの詳細を知っているだろう

+0

こんにちはHardCode、私はよくこの感情を表明していると聞いてきました。私が挑戦しようとしているのは、具体的な/再現可能な例です。 – Oorang

+0

VB6のガベージコレクションメカニズムに問題はありません。参照を適切に解放しない、またはそれを破る非常に特殊なティアダウンセマンティクスを必要とするその他のコンポーネントです。ルールに従わないコンポーネントの記述が悪いというのはVB6の欠点ではありません。 –

+4

時には、循環オブジェクト参照のようなものも明示的に破棄する必要があることがあります。一般的に、scope-exitはローカルのrefenceを解放し、配列の割り当てを解除しますが、module-globalデータのような長期間のスコープでは、メモリリソースを解放するために早期に機会を取って早期に掃除することを勧めます。 ポイントはただの一般的なルールではありません。あなたは何をやっているのか、早期の割り当て解除に価値があるのか​​を意識する必要があります。 – Bob77

13

マットCurland、Advanced Visual Basic 6の著者は、それは無駄な努力であると考えています。

悪質なティアダウンコードの別の例:DAO(Access Data Engine)を主に対象とするCOMデータアクセスライブラリに関するこの引用文(p110)を検討してください。 DAOには、正しい順序で という名前のCloseメソッドがあり、 オブジェクトは、正しい順序で のオブジェクトとしてリリースする必要があります(たとえば、データベースの前にRecordset など)。この 単一の貧弱なオブジェクトモデルの動作は、 を明示的にすべての を関数の末尾の に何も設定しない限り、VB漏れが という誤解につながりました。これは、 のよく設計されたオブジェクトモデルで完全に偽の概念である です。あなたがコードからできるよりもVBは エンド サブラインでより高速な変数をクリアすることができ、かつ を明示的にあなたの参照を解放 場合でも、それは変数をチェックします。 あなたの努力は重複しています。

+0

こんにちはODW、これは思考の私の考えを平行します。 DAOは私がWin32の外で正しくリリースされなければならないことが分かっていた唯一のオブジェクトです。あなたは他の "特別な事件"を知っていますか? – Oorang

2

Aivosto web page(Project Analyzerの作成者から)を読んでいますか?

あなたは静的変数を使用している場合は、 それはあなたがこれ以上 の変数を必要としないとき、彼らは占有メモリ を再利用することが重要です。動的な の変数メモリは、手順が終了すると が破壊されているので、 の問題ではありません。

つまり、通常の静的でないローカル変数をクリアすることを心配する必要はありません。

+0

+1それに気付いて:)私は静的を使用しているときはかなりまれですが。私は何かが記憶されている必要がある場合、私は通常プライベートモジュールのレベル変数を使用します。 – Oorang

関連する問題