2013年10月26日土曜日

コラム:FileSystemObjectとNothing

 『FileSystemObjectのオブジェクトは解放しなければならない。』は本当?

        Dim fso as new FileSytemObject
           ・
           ・
     ・
         Set fso = Nothing


 前々から気になっていたVBAのガーベージコレクションの動作について、検証を試みました。なにが気になっていたかというと・・・

【気になっていたこと】
  VBAってガーベージコレクション機能があるんじゃないの!
  なんでオブジェクトを作ったあとにNothingを代入してメモリを解放するの?
  これじゃ、CやC++と同じじゃない!めんどうくさい。


 VBAを使い始めたころは、ネットのコードをまねして、必ずNothingを使って”きれいに”していました。しかし、最近では、もともとのいいかげんな性格がでてきて、Nothingを使わなくなりました。それでも、これまでメモリ不足なんて見たことはありません。



  さて本題です。解説が長くなりそうなので、検証結果から。

【検証総合結果】

  VBAのコード実行が終了すると、ガーベージコレクションが”きちんと”働き、Nothingを代入していないFileSystemObjectが自動で解放されている。
  したがって、何時間も何日も実行しつづける関数を実行しない限り、Nothingを使って解放する必要はない。



【検証】
   ①現在のメモリ情報を取得する関数を実行する。
   ②FileSystemObjectを100万個つくるだけの関数を実行する。
     (Nothingによる解放をしない)
   ③現在のメモリ情報を取得する関数を実行する。

   フリー物理メモリ
     ①    1,687,674,880バイト
     ②-1  1,687,359,488バイト(②の関数のはじめでチェック)
     ②-2  1,686,659,072バイト(②の関数のおあわりでチェック)
     ③    1,687,969,792バイト


   確かに②の関数内では、Nothingで解放していないため、700kバイトの
  メモリが使われているのがわかる。
   しかし②の関数を抜けてしまうと、700kバイトのメモリは解放されている。
   (逆に増えているのは、その他の要因か)

     10回ほど繰り返したが、全部同様の結果となった。

   尚、FileSystemObjectは1個につき7バイトを使用することも分かった。

   心配することなかれ、VBAのガーベージコレクションは、”きちんと”
  働いてくれているのだ。


【コード1】メモリの状態を取得する

Private Declare Sub GlobalMemoryStatus Lib "kernel32" (lpBuffer As MEMORYSTATUS)

Public Type MEMORYSTATUS
    dwLength As Long
    dwMemoryLoad As Long
    dwTotalPhys As Long
    dwAvailPhys As Long
    dwTotalPageFile As Long
    dwAvailPageFile As Long
    dwTotalVirtual As Long
    dwAvailVirtual As Long
End Type

Function GetMemoryInfo() As MEMORYSTATUS
    
    Dim memInfo As MEMORYSTATUS
    GlobalMemoryStatus memInfo
    GetMemoryInfo = memInfo

End Function


【コード2】FileSystemObjectを指定しただけつくる

Sub testFSO2(numFSO As Long)

    Dim index As Long
    Dim fso() As FileSystemObject
    
    ReDim fso(numFSO)
    
    For index = 0 To numFSO - 1
        Set fso(index) = New FileSystemObject
    Next
    
    ReDim fso(1)

End Sub



今日はここまでです。

<script data-ad-client="ca-pub-1118677719612861" async src="https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js"></script>

0 件のコメント:

コメントを投稿