VBA関数の内部Nothingにオブジェクトを設定する必要があります
-
21-08-2019 - |
質問
私はいつも私は彼らと一緒に行っていたら、何にオブジェクトを設定することを推奨されていることを読みました。しかし、私は通常、フォーム内の関数だけでそれらを使用します。
は関係なく、Nothingにオブジェクトを設定する、関数のスコープが残っているときに解放失わ参照し、メモリはありませんか?
すなわち。行うには、それが本当に必要です。
Set db = Nothing
Set record_set = Nothing
解決
VBは、いわゆる「参照カウント」ガベージコレクタを使用します。
基本的には、変数がスコープの外に出る瞬間は、参照されたオブジェクトの参照カウンタがデクリメントされます。あなたが別の変数へのオブジェクト参照を割り当てると、参照カウンタがインクリメントされます。
カウンタがゼロに達すると、オブジェクトは、ガベージコレクションの準備ができています。オブジェクトのリソースはすぐにこの問題が発生したとしてリリースされます。関数が終了したときに機能ローカル変数最も可能性の高い参照回数1より高くなることはありませんオブジェクトを参照するため、リソースをオブジェクトになるが解放されます。
Nothing
する変数を設定すると、明示的に参照カウンタを減少させる方法である。
たとえば、ファイルを読み込み、右Nothing
コールの後ReadAll()
するファイルオブジェクト変数を設定します。ファイルハンドルがすぐに解放され、あなたはあなたの時間のプロセスにその内容を取ることができます。
あなたがNothing
に設定されていない場合は、ファイルハンドルが絶対に必要以上に長く開いているかもしれません。
あなたは状況の「貴重なリソースのブロックを解除しなければならない」ようなものになっていない場合は、単にせる変数がスコープの外に出るが、大丈夫です。
他のヒント
ガベージコレクションはほとんど完璧です。でも.NETであなたが強く、早期ガベージコレクションを行うためのシステムを促すために奨励されている時間があります。
このため、I明示的に両方の閉じると私は彼らと一緒に行っていたときのなしのレコードに設定されます。
Recordset.Close 」マイクロソフトのDAOのヘルプとAccessの開発の参考にこれです:
「Closeメソッドに代わるものです オブジェクト変数の値を設定します Nothingに(設定dbsTemp = Nothing)で。」
http://msdn.microsoft.com/en-us/library/ bb243098.aspxする
は、このことを念頭に置いては、Microsoft Knowledge Baseからこの記事のrel="noreferrer">
http://support.microsoft.com/kb/289562する 現象:Microsoft Accessデータベース
肥大化(またはで急速に成長し始めています
あなたがデータアクセスを実装した後のサイズ)
レコードセットを開くためのオブジェクト(DAO)。 原因:あなたは解放しない場合
レコードセットのメモリあなたたびに
レコードセットコード、DAOをループ
より多くのメモリを使用して、再コンパイルすることができ、
データベースのサイズを増やします。 詳細:作成
レコード(またはクエリ定義)オブジェクト内
コード、明示的にオブジェクトを閉じたときに
作業は完了です。 Microsoft Access
自動的に閉じレコードと
最も下のクエリ定義オブジェクト
状況。しかし、あなたの場合
明示的にオブジェクトを閉じます
コード、あなたは時折避けることができます
インスタンスオブジェクトが残っています
オープンます。 最後に、私は15年間、Accessデータベースで作業されていることを追加してみましょう、と私はほとんど常に私のローカルで宣言レコードセット変数を明示的にCloseメソッドを使用せずに、スコープの外に行きましょう。私はそれを上の任意のテストを行っていないが、問題ではしていないようです。
の参照は、変数がスコープ外になったときにクリーンアップされることになっています。おそらくこれは、ソフトウェアの新しいバージョンで改善されているが、それは一度信頼できないでいました。私はそれが明示的に変数を設定することをお勧めままであることを信じている「何もない。」
あなたはASPクラシック(サーバーサイドのスクリプト)を使用している場合は、それはあなたが彼らとているとき、[仮想]サーバーがシャットダウンされるまで、彼らはスコープの外に出ていないので、何もすべてのオブジェクトを設定するためのインポートがあります。
このような理由から、すべてのMS VBスクリプトの例は、常に何も閉じて設定されているオブジェクトを示しました。スクリプトの抜粋は、オブジェクトがスコープ外に行かなかったASPの古典のような環境で使用することができるようにます。
あなたは、オブジェクトがスコープ外に行かない、と明示的にオブジェクトを解放しない場合、あなた自身が、物理メモリが不足して見つける長時間実行中のプロセスをコーディングしたい他の状況は、めったにありません。
あなた自身がASPの古典的なコーディング、または他のいくつかの理由のためにグローバルスコープで実行中のプロセスを見つけた場合は、、[はい、あなたは明示的にオブジェクトを解放する必要があります。
私は通常、常に私の手順の最後にこれを置くか、私はモジュールレベルのものを使用している場合にはそれを「CloseRecordSet」サブを呼び出します:
Private Sub Rawr()
On Error GoTo ErrorHandler
'Procedural Code Here.
ExitPoint:
'Closes and Destroys RecordSet Objects.
If Not Recset Is Nothing Then
If Recset.State = 1 Then
Recset.Close
Conn.Close
End If
Set Recset = Nothing
Set Conn = Nothing
End If
Exit Sub
ErrorHandler:
'Error Handling / Reporting Here.
Resume ExitPoint
End Sub
ただし手順が終了した方法は、オブジェクトがクリーンアップされ、リソースがフリーである(通常またはエラーのためにそれをすること)。
それはすでに起因して(閉じられていた包みその方法は、あなただけでそれを平手打ちすることができ、それが唯一の決算に関して必要である何だろう、またはレコード/接続オブジェクトを破壊するということで非常に安全であることをやってランタイムエラーや屋が、これはちょうど確かめる必要があるとしてだけで)早くそれを閉じます。
あなたはすぐに関係なく、プログラムの中で何が起こるかのリソースを解放するためにそれらを終了したら、あなたのオブジェクトをクリーンアップするには、その本当にあまり手間とその常に最高ます。
これを試してみてください。
If Not IsEmpty(vMyVariant) Then
Erase vMyVariant
vMyVariant = Empty
End If