- 題名: メモリ使用量が解放されない
- 日時: 2006/08/29 3:03:50
- ID: 17329
- この記事の返信元:
- (なし)
- この記事への返信:
- [17331] Re[1]: メモリ使用量が解放されない2006/08/29 8:45:40
- [17334] Re[1]: メモリ使用量が解放されない2006/08/29 8:53:00
- [17390] Re[1]: メモリ使用量が解放されない2006/09/01 2:33:50
- ツリーを表示
■No17329に返信(maskさんの記事) > 私の考えでは、解放(Erase)のタイミングで(多少の時間誤差はあると思うが)、 > タスクマネージャのメモリ使用量は、ある程度解放されるものと認識していたのですが、 > 数分待っても一向に解放される気配がなく、ずっと数百メガの使用量を維持し続けます。 > Eraseではなく、配列 = Nothing でも同じ現象でした。 ためしに、GC.Collect メソッドで強制的にガベージ コレクトしても変化なしでしょうか? > VB6.0のときには、上記方法で解放されていたと思うのですが、.Netになってからは、 > 何か仕様的に変わってしまったのでしょうか? これに関していえば、参照カウント法からガベージ コレクションへと変わっています。 これをご存知だからこそ、"数分待った" のではないのでしょうか? > それとも、.Netでの配列等の解放についての私の認識が間違っているのでしょうか? 解放という概念を持ち込む必要がないという意味では、誤りがあるのかもしれません。
次のようなクラスを作ってみました。 Class Test Private Const ARRAY_SIZE As Integer = 10000 Private m_x()() As String Private m_xCount As Integer Private arrayCount As Integer Private lastIndex As Integer ReadOnly Property XCount() As Integer Get Return m_xCount End Get End Property Public Sub New() ReDim m_x(0) m_x(0) = New String(ARRAY_SIZE - 1) {} arrayCount = 1 lastIndex = -1 End Sub Public Sub AddX(ByVal x As String) If lastIndex < ARRAY_SIZE - 1 Then lastIndex += 1 Else ReDim Preserve m_x(arrayCount) m_x(arrayCount) = New String(ARRAY_SIZE - 1) {} arrayCount += 1 lastIndex = 0 End If m_x(arrayCount - 1)(lastIndex) = x m_xCount += 1 End Sub Public Function X(ByVal i As Integer) As String Dim arrayNumber As Integer = i \ ARRAY_SIZE Dim index As Integer = i Mod ARRAY_SIZE Return m_x(arrayNumber)(index) End Function End Class これを用い、以下のように1024^2(=1M)回ループさせたところ、所要時間は2秒弱、 メモリ増加量は38MBでしたので、データ1個(すべて7桁の文字列)あたり38バイトの 増加となります。 Dim t As New Test For i = 1 To 1024 * 1024 t.AddX((i + 1000000).ToString) Next また、maskさんのプログラムのようにt.AddX("test")としてみると、一瞬で終了し、 メモリの増加量は4.6MBでした。 この場合、文字列の実体は1個しか確保されないので、配列に格納される4バイトの 参照値×件数の分しかメモリは消費されないはずですが、その予想に一致した結果と なっています。 私はコレクションの知識もほとんどない初級アマチュアですのでこの程度しか思い つきませんが、ご参考になれば幸いです ---------- 追記です。やはりもっと簡単な方法がありましたね。No17412をご覧下さい。m(_ _)m
分類:[.NET]
はじめまして。maskと申します。
現在、VB.Netでの開発を行っておりまして、1つ解決できない問題がありますので、
ご存知の方がいらっしゃいましたら、どうかご助言お願いいたします。
内容としては、ある処理をループしている個所があり、数千件単位でループさせると、
タスクマネージャのメモリ使用量がどんどん増加していくということです。
このループ内で行っている処理として、大きく分けて、@配列が解放されない Anew
したオブジェクトが解放されない の2点が考えられるかと思っております。
そこで上記のことから、テスト的にちょっとしたテストプログラムも作成してみました。
これは、単純に数千件〜数万件のループ処理で、配列のRedim Preserveを行い、メモリ
領域を増やしながら、値も適当に設定していく単純なものです。
もちろん、最後の処理として配列の解放(Erase)も行っています。
また、exeにする際に、リリースビルドでコンパイルもしております。
このプログラムでもやはり同様のことが発生します。
私の考えでは、解放(Erase)のタイミングで(多少の時間誤差はあると思うが)、
タスクマネージャのメモリ使用量は、ある程度解放されるものと認識していたのですが、
数分待っても一向に解放される気配がなく、ずっと数百メガの使用量を維持し続けます。
Eraseではなく、配列 = Nothing でも同じ現象でした。
VB6.0のときには、上記方法で解放されていたと思うのですが、.Netになってからは、
何か仕様的に変わってしまったのでしょうか?
それとも、.Netでの配列等の解放についての私の認識が間違っているのでしょうか?
上記内容に不明点等ある場合は、再度補足説明もしたいと思いますので、この件について
何かご存知の方は、どうか書き込みをお願いいたします!!