VB6(OSは、2000 or xp)のメモリ開放に関して疑問点があります。
プロシージャ内で
Set a As New b
とか
Set a As b
オブジェクト変数は、プロシージャ内で
Set a = Nothing
としないとプロシージャから抜けてもメモリは開放されないのでしょうか?
また、プロシージャ内で宣言した動的配列もEraseで開放しないとプロシージャから抜けてもメモリは開放されないのでしょうか?
フォームのモジュールで宣言したオブジェクト変数や動的配列の場合、フォームをアンロードして(Nothingにして)もメモリは自動的に開放されるわけではないのでしょうか?
また、フォームはアンロード後Nothingにしないと、メモリは開放されないのでしょうか?タスクマネージャで見ると、フォームをアンロードするだけでメモリは減っているようなのですがヘルプを見るとNothingにしないといけないように書いてあるので疑問です。
>としないとプロシージャから抜けてもメモリは開放されないのでしょうか?
スコープを抜けるとメモリーは解放される。
>フォームのモジュールで宣言したオブジェクト変数や動的配列の場合、
>フォームをアンロードして(Nothingにして)もメモリは自動的に開放されるわけではないのでしょうか?
上の理由でメモリーは解放される。
>また、フォームはアンロード後Nothingにしないと、メモリは開放されないのでしょうか?
これも開放される。
>ヘルプを見るとNothingにしないといけないように書いてあるので疑問です
nothingのHelpには
>複数のオブジェクト変数が同じオブジェクトを参照すると、
>各変数が参照するオブジェクトに関連付けられたメモリとシステム リソースは、
>Set ステートメントを使ってすべての変数を明示的にキーワード Nothing に設定するか、
>またはキーワード Nothing に設定した最後のオブジェクト変数が、暗黙のうちに適用範囲
>(スコープ) 外になった後でなければ解放されません。
と書かれてい
我龍院忠太さん、Resありがとうございます。
プロシージャを抜けるとその中で宣言された変数は開放されるということですね。
プロシージャの呼び出し元でOn Error GoTo xxx としてあって、プロシージャ内でエラー発生して呼び出しもとのエラールーチンに飛んだ場合等もメモリは正常に開放されるのでしょうか?
NothingのHelpに書かれている内容を読んで、Nothingに設定しないで適用範囲外になると開放されないんじゃないかと思ったんですが、解釈が間違っていますか?
また、フォームの有効期間のHelpには、
>フォームのメモリを解放するには、この変数を Nothing に設定する必要が
>あります。たとえば、次のように設定します。
>
>Set Form1 = Nothing
と書いており、やはり、Nothingにしないと開放されないように解釈してしまったんですが。
エラー処理は関係有りません、プロシジャー内で宣言した変数は、
静的変数を除いて、プロシジャーを抜けると開放されます。
>フォームのメモリを解放するには、この変数を Nothing に設定する必要が
>あります。たとえば、次のように設定します。
>
>Set Form1 = Nothing
主語と述語を正しく解釈しないといけません。
「この変数」は「フォームを参照したことがある隠されたグローバル変数」をさしています、
つまりフォームをUnloadしても、そのフォームを参照しているグローバル変数が存在している
かぎりは、フォームのメモリは解放されません。
我龍院忠太さん、再度の解説ありがとうございます。
単純に
Load フォーム名
としたら、参照している変数は無いのでフォームをアンロードしたらメモリは解放されるということですね。
ActiveX等も使い終わったらNothingにしないといけないと書いてあるのを見かけますが、その変数が適用範囲外になるまでメモリをとっていても問題なければ、Nothingにしなくても良いうことですね。ただ、ActiveX exeをグローバル変数で参照して、そのアプリをEndで終了したら、ActiveX exeは、タスクマネージャに残ったままになっていたので、正常な終了をしなかった場合は開放されないという認識でよいのでしょうか?エラーでプロシージャを抜けるのは、正常な処理でちゃんとメモリを開放してくれるはずなのですね。
変数の生存期限とオブジェクトの生存期限の問題というのなら、
単純にそれぞれ別ですので同じ舞台に挙げない方が混乱しないと思います
# 開放と解放では、意味が微妙に異なるかも。
> Load フォーム名
> としたら、参照している変数は無いので
この時の「フォーム名」が、『参照している変数』ですよね。
> アンロードしたらメモリは解放されるということですね。
Unload されただけでは、まだそのフォームは存在していますし、
Nothing が代入されても、Unload されていなければ、やはり残ります。
それぞれのフォームに、下記のようなコードを埋め込んで、どのタイミングで
Terminate イベントが発生するのか、チェックしてみてください。
--------
Option Explicit
Private Sub Form_Initialize()
Debug.Print "作成"; ObjPtr(Me)
End Sub
Private Sub Form_Load()
Debug.Print "ロード"; ObjPtr(Me)
End Sub
Private Sub Form_Unload(Cancel As Integer)
Debug.Print "アンロード"; ObjPtr(Me)
End Sub
Private Sub Form_Terminate()
Debug.Print "解放"; ObjPtr(Me)
End Sub
----------
この Initialize / Terminate イベントのコードは、Form だけでなく、
Class モジュールにも応用出来ますので、どのタイミングでオブジェクトが
開放されるのかを追跡するのに使えるかと。
ガッさん、魔界の仮面弁士さん、ありがとうございます。
返事が遅くなってすみません。
質問しなくても、試してみたら分かるようなことでした。
皆様に無駄な労力を掛けてしまったようで申し訳ありません。
魔界の仮面弁士さんには、誤字まで指摘されて恥ずかしい限りです。
ObjPtrという関数もはじめてみました。Helpを見てもなかなか出てこないような技がしょっちゅう出てくる魔界の仮面弁士さんの知識にはいつも感心します。
| ツイート |
|