VB6 VBAでのメモリ解放について

このQ&Aのポイント
  • VB6やVBAで動的配列を解放した場合、タスクマネージャーで確認してもメモリの解放が反映されないことがあります。解放してもメモリが減らない原因や解決策について知りたいです。
  • 動的配列の内容を表示させるたびにメモリが減り、EraseやRedimを行ってもメモリが解放されない現象に遭遇しました。APIを使ってメモリを解放する方法や、.NETでのメモリ解放についても教えてください。
  • VB6やVBAでのメモリ解放について質問です。動的配列を解放した後でもメモリの使用量が変わらないことがあります。メモリ解放の方法や、.NETではどのようにメモリを解放するのかについて教えてください。
回答を見る
  • ベストアンサー

メモリの解放について VB6 VBA

VB6やVBAで動的配列をERASEしたのですが、タスクマネージャーで見ても使っているメモリを解放しているように見えません。 動的配列の内容をMsgBoxで表示させるたびにメモリがどんどん減っていきます。Eraseしても戻りません。 Redim ArryaDat(0)とかでも無理でした。 APIを使って(どんな方法)でも、メモリを解放したいのですが、可能でしょうか? Dim ArrayDat() as String Redim ArrayDat(100) ArrayDat(0) = "なんとか" ArrayDat(1) = "かんとか" ... ArrayDat(100) = "メモリを解放したい" for i = LBound(ArrayDat) to UBound(ArrayDat) MsgBox("どんどんメモリが消費されていく・・ [" & ArrayDat(i) & "]") next i Redim ArrayDat(0) Erase ArrayDat NsgBox("解放したつもり? 誰か教えて") あと、.NETではメモリ解放はどうなっているのでしょうか? まだ使いませんが、頭の片隅に入れておきたいです。

質問者が選んだベストアンサー

  • ベストアンサー
  • kero_mio
  • ベストアンサー率90% (94/104)
回答No.1

Erase は、配列の要素をクリアしただけで、エリアとしては 確保されています。 完全に解放させるには、Nothingを代入させないと解放されません。 Set ArrayDat = Nothing また、APIでメモリ解放する場合は、APIを使って割り当てたメモリ で良く使用しますが、今回の場合は、そこまで行っていないと 思います。 ご検討下さい。

関連するQ&A

  • VB6のメモリ解放に関して

    お世話になります VB6のメモリ解放に関して、以下を参考に下記のコードで試したのですが、 コンパイルエラーで「配列には割り当てられません」となってしまいます。 http://okwave.jp/qa/q3372573.html 違いは宣言の型がStringかLongしかないと思うのですが、 なにが悪いのか教えていただけないでしょうか ******* 以下 ソース Dim wProcDat() As Long ReDim wProcDat(1 To 1000, 1 To 768) 中略 Set wProcDat = Nothing

  • VBの配列 IsNull, IsNuthing, ...? 用途がわかりません。

    以下の場合、(1)で範囲エラーとなります。 redim a(0)とすると、a配列に1個データがあるということで、for文が実行されますが。 Redimしないまま(データが無い意味としたいので)で、このFor文をパスするには、どのように記述すればよいのでしょうか? dim a() as string '----->(2) for i=LBound(a) to UBound(a) '---->(1) msgbox(a(i)) next i

  • 配列をEraseしてもメモリが開放されていない?

    すみません。一度質問を載せた後で、補足で絵を載せようとしたのですができなかったので 再投稿させていただきます。(元の質問はけしました。) -------------------------------------- こんにちは、今作成しているエクセルのVBAで配列を膨大に食ってしまい、メモリ不足に落ちいるという現象に悩まされています。 そのため、なるべくいらなくなった配列はEraseステートメントを使って解放しようとしてるのですが、 これが上手くいっている気がしません。 ためしにフォームと、ラベルを1つずつ用意し、下記のような配列をどこまで作れるか計算するプログラムを組んでみました。 1回目、ans(i) に"a"というaを1個のみ格納した場合で計算すると、配列は2970万個できます。 2回目、ans(i) に"aaa~a"というaを64個格納した場合で計算すると、配列は770万個できます。 まぁ、ここまでは当然の結果だと思います。 可変長のString型変数の場合は、割り当てられるメモリサイズが固定ではないらしいので (前回の質問で教えてもらいました) しかし3回目、ここでもう一回、1回目と同じ、"a"を一個のみ格納した場合で計算してみます。 私の予想では1回目と同じ2970万個程度の配列が作れると思っていました。 なぜなら、Eraseステートメントでメモリを解放していたし、 タスクマネージャーのPF使用量(おそらくメモリの値)を見ても2回目を実行した後の値は 1回目前と同じ値に戻っているからです。 しかし、実際試してみると、 2回目と同じ770万個の配列しかつくれませんでした。 つまり、Eraseステートメントを使用しても配列の上限値は元の状態に戻らなかったのです。 どうすれば、配列を再び2970万個作れる初期の状態に戻せるのでしょうか? 現時点ではエクセルを起動しなおせば、元に戻りますが、それでは困ります (プログラムの途中で配列の数を減らしたり、コピーしたりを行っている為、 どうしてもプログラム中でメモリの解放を行いたいからです) また、添付した絵は、実行した時のタスクマネージャーの様子です。 参考になれば幸いです どうか、みなさんお知恵をお貸ししてください --------------------------------------------------- '実行するときは、フォームとラベルを1つずつ用意して実行してください Public Sub 配列上限取得計算() On Error GoTo ErrEnd Dim i As Long Const kankaku As Long = 100000 Dim ans() As String ReDim ans(1 To kankaku) As String ans(1) = 1 i = 2 UserForm1.Show vbModeless Do If i Mod kankaku = 0 Then DoEvents UserForm1.Label1 = i ReDim Preserve ans(1 To i + kankaku) As String End If '最初にaを1個のみ格納した場合は、2970万個まで配列が作れるが、次にaを64個格納した場合は770万個まで作れた。 'しかし、その直後にまた、aを1個のみ格納した場合で実行してみると、770万個しか作れない 'つまり、Eraseステートメントを使っているにも関わらず、同じ条件のプログラムでも配列の上限が下がってしまう。 'この現象をなんとか回避したい。元の状態にリセットするにはエクセルを起動しなおさないと直らない。 '1回目と3回目に実行するコード、2回目はコメントアウトしてください ans(i) = "a" '2回目に実行したコード、2回目はコメントアウトを解除してください。 ' ans(i) = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" i = i + 1 Loop Erase ans Unload UserForm1 Exit Sub ErrEnd: Erase ans MsgBox "これ以上の配列を設定できません。" & vbCrLf & "上限は" & i & "です。" & vbCrLf & Err.Description Unload UserForm1 End Sub

  • 動的配列の後始末?

    以下のサブルーチンで、lines()と動的配列を定義して、Splitでデータを入れたのですが、このサブルーチンが終了すると、lines()はデータも含めて解放されるのでしょうか? 極端な話、1億回このサブルーチンを呼ぶと、メモリーリークするのでしょうか? それと、VB6やVB.NETでは、For文・For Each文のどちらを使う方が良いのでしょうか? Sub test() Dim lines() As String lines = Split(Data, vbCrLf, -1, vbBinaryCompare) Dim i As Integer For i = LBound(lines) To UBound(lines) MsgBox ("for=[" & lines(i) & "]") Next i Dim s As Variant For Each s In lines MsgBox ("for each=[" & s & "]") Next End Sub

  • 二次元配列のVBA

    二次元配列のVBAの書き方がよくわからないのですが、 私が作ったサンプルプログラムのSub 二次元()において 二次元配列で表すにはどうすればいいのでしょうか? Sub 二次元()では 配列を格納する変数はtmpしか使っていませんが もう一つ配列を格納する用の変数を作ればいいのでしょうか? 数字とアルファベットは別々に取り出したいです。 ----------------------------------------------------- Sub 一次元() Dim myStr As String Dim tmp As Variant Dim i As Long For i = 1 To 5 myStr = myStr & "," & i Next myStr = Mid(myStr, 2) tmp = Split(myStr, ",") For i = LBound(tmp) To UBound(tmp) Debug.Print tmp(i) Next i End Sub Sub 二次元() Dim myStr As String Dim tmp As Variant Dim i As Long For i = 1 To 5 myStr = myStr & "," & i & "と" & Chr(64 + i) Next myStr = Mid(myStr, 2) tmp = Split(myStr, ",") For i = LBound(tmp) To UBound(tmp) Debug.Print tmp(i) Next i End Sub

  • Excelのメモリ(配列)の上限は2Gではないのか

    こんにちは、 現在ExcelのVBAで大量に配列を必要なマクロを作成しています。 その為、計算量が増えるとどうしても、 メモリ不足というエラーが発生してしまい困っています。 そこで、現在使っているExcelがどれだけの配列とメモリを使用できるのか 下記コードを使用してテストしてみました。 そうすると、下記のような値の時メモリ不足というエラーが発生してマクロが終了しました (下図参照) ・メモリ(プライベートワーキングセット)  :1249716 K (約1G?) ・String型配列数(各要素"01,02,03,04,05,06") :約28000000(2800万個) 私の知識では、32bitアプリケーションのメモリの上限は2Gだと聞いています。 ですが、実際にはその半分しか使われていません。 そこで質問となるのですが ・32bitアプリケーションの上限が2Gと言われているのはプラベートワーキングセットの値のことではないのか? ・32bit版Excelを使用して、これ以上のメモリ(配列)を使用することは可能か ・可能であれば、その方法はどんな方法か? 以上のことについてお聞きしたいと思っております。 上のどれか一つでもいいです。知っていることがあれば教えてください。 補足となりますが、テストしたPCの簡単な環境を下に記載して置きます。 どのPCでも上記結果とほぼ変わりはありませんでした。 PC1 Windows7 32bit メモリ 4G Excel2013(32bit) PC2 Windows7 64bit メモリ 8G Excel2010(32bit) 以下は使用したプログラムコードです --------------------------------------------------------------- Public Sub 配列上限取得計算() On Error GoTo ErrEnd Dim i As Long Const kankaku As Long = 1000000 Dim Moji As String Moji = "01,02,03,04" Dim ans() As String ReDim ans(1 To kankaku) As String i = 1 Do If i Mod kankaku = 0 Then ReDim Preserve ans(1 To i + kankaku) As String End If ans(i) = Moji i = i + 1 Loop Erase ans Exit Sub ErrEnd: MsgBox Err.Description & vbCrLf & "これ以上の配列を設定できません。" & vbCrLf & "上限は" & i & "です。" Erase ans Err.Clear End Sub

  • 配列について。

    Redim した後   For i LBound(配列) To UBound(配列)    作業   Next i をしているのですが、配列の要素数を別プロセスで 計算させる場合、必ずしも要素が存在するとはかぎ りません。 その場合エラーがでるわけですが、このように配列 の中身が存在しない場合はどのように回避できるの でしょうか? VB6&Windows2000です。

  • VB.netでの動的配列の扱い

    VB.net 2003で開発を行っています。 コード内で動的配列を多用しているんですが(要素数 2000000以上)、一度 ReDim でメモリ確保した配列は、いらなくなったと同時にErase したほうがいいんでしょうか。 配列を増やすほど実行速度が遅くなっていく気がします。 また、いっそのことVC++で書き直すと、実行速度は速くなる可能性はありますか。 VB.netのコードは、もちろん最適化のチェックをすべていれてあります。 どなたかご教授下さい。

  • dim を解放

    VBスクリプト です。 DIMで宣言された変数を解放するにはどうすればいいでしょうか? DIM myfilename myfilename="ああああああ" このときmyfilenameには「ああああああ」が入っていますが、これを空。初期状態に戻すにはどうすればいいでしょうか? redim filename としたら()がないとか言われてエラーでした。 ()つけてもエラーでしたけど。 今 http://www.okweb.ne.jp/kotaeru.php3?q=281720 の疑問を解決しようとVBスクリプトで作成していきづまってるところです。

  • ReDim PreserveよりもReDimが遅い

    こんにちは、配列がいくつまで取得できるのか計算するマクロを作っている時に変なことに気が付きました。 エクセルでフォームとラベルを1つ用意し、下記のようなプログラムをモジュールに書きます。 実行すると、10万ずつ数字が増えていき、数字が1000~2000万超えたあたりで、メモリ不足ですという 表示がでます。 ここで、ReDim PreserveのPreserveをとって、ReDimだけにすると、数字の増え方が目に見えて遅くなります。 ReDim Preserveとしたときは9.5秒ぐらいですが ReDim の時は 30秒以上かかっています 3台のマシンでテストしましたが、どれも似たような結果になりました 普通に値を保持するredim Preserveの方が遅いと思うのですがなぜこのような結果になるのでしょうか? ご教授お願いいたします。 Public Sub 配列上限取得計算() On Error GoTo ErrEnd Dim i As Long Const kankaku As Long = 100000 ReDim ans(1 To kankaku) As String ans(1) = 1 i = 2 UserForm1.Show vbModeless Do If i Mod kankaku = 0 Then DoEvents UserForm1.Label1 = i 'ここのPreserveをなくすと明らかに遅くなる ReDim Preserve ans(1 To i + kankaku) As String End If ans(i) = i i = i + 1 Loop Erase ans Unload UserForm1 Exit Sub ErrEnd: MsgBox "これ以上の配列を設定できません。" & vbCrLf & "上限は" & i & "です。" & vbCrLf & Err.Description Erase ans Unload UserForm1 End Sub

専門家に質問してみよう