|
■No81901 (sk さん) に返信 >>Release ビルドにおいて、60時間22分58秒後 に停止しています。 > 再現してしまいましたか・・。
タイマーを使わずに無限ループさせてみましたが、やはり 57時間ともたずに、 型付きな DataSet1 生成が停止してしまいました。
今回はコンソールアプリとしての実行です。
----------------- 71,582,789 回目 InitClass 内の行位置: 1,150 …… DataSet1 内の15個目のテーブルをNewしている最中 DataSet1 : before [BeginInit()] DataSet1 : before [InitClass()]
-----------------
※実行回数 71,582,720 時点の累積時間は 2日と8時間56分59秒4931635
コンストラクタが完了待ちのままになっているというだけであり、プロセス自体は 停止していません。Console.CancelKeyPress イベントによる割り込みは可能でした。
また、今回の検証時、GC.GetTotalMemory も計測していましたが、 常時、数 MB というサイズを維持して上下動しており、 GC が間に合っていないというわけでもなさそうに思えます。
GC.GetTotalMemory の最小値は 70,796 最大値でも 7,96,084 という結果です。
処理停止後の GC.GetTotalMemory は 3,524,268 バイトでしたが、 停止後に GC を強制発動してみたところ、242,412 バイトまで減少しました。 それでもプログラムが再開する様子はありません。
参考までに、今回の計測プログラムを掲載しておきます。
Imports System Imports System.Data Imports System.Diagnostics Imports System.Linq Imports System.Threading
'1 = 型付 DataSet で検証 '2 = 素の DataSet で検証 #Const TYPED_DATASET = 1
Module Module1 Private Cancel As Boolean = False Private Const LoopMax As Integer = 256 '連続生成数
Private _i As Integer '処理回数
''' <summary>ログ出力</summary> #If TYPED_DATASET = 1 Then Private Function GetLog() As String Return _i.ToString("#,0") & " 回目" & vbCrLf & DataSet1.GetLog() End Function #Else Private Function GetLog() As String Return _i.ToString("#,0") & " 回目" & vbCrLf & "Table:" & _table.ToString("#,0") & vbCrLf & "Column:" & _column.ToString("#,0") End Function Private Const TableCount As Integer = 60 Private Const ColumnCount As Integer = 80 Private _Log As String Private _table As Integer Private _column As Integer #End If
Sub Main() '[Break] もしくは [Ctrl]+[C] で割りこみ処理 AddHandler Console.CancelKeyPress, _ Sub(sender, e) Dim msg = "中止 => 計測停止" & vbCrLf & "再試行 => GC.Collect を発動して継続" & vbCrLf & "キャンセル => (何もしない)" & vbCrLf Dim style = vbAbortRetryIgnore Or vbQuestion Or vbDefaultButton3 Or vbMsgBoxSetForeground Select Case MsgBox(msg & vbCrLf & GetLog(), style) Case vbAbort Cancel = True Case vbRetry Dim before = GC.GetTotalMemory(False) GC.Collect() GC.WaitForPendingFinalizers() GC.Collect() Dim after = GC.GetTotalMemory(True) MsgBox("GC結果" & vbCrLf & String.Format( "発動前: {0,15:#,0}" & vbCrLf & "発動後: {1,15:#,0}", before, after), vbInformation) Case vbIgnore REM DoNothing End Select e.Cancel = True End Sub
'負荷テスト Do Module1._i = 0 Dim curMem As Long = 0 Dim minMem As Long = Long.MaxValue Dim maxMem As Long = Long.MinValue Dim sw As Stopwatch = Stopwatch.StartNew() Cancel = False While Module1._i < (Int32.MaxValue - LoopMax) Dim counter = String.Format("実行回数 {0,-16:#,0}" & vbTab, Module1._i)
Console.SetCursorPosition(0, 0) Console.WriteLine(counter) Console.WriteLine("現在時刻 " & Now.ToString("yyyy/MM/dd HH:mm:ss.fffffff")) Console.WriteLine("累積時間 " & sw.Elapsed.ToString("G")) Dim oldMem = GC.GetTotalMemory(False) minMem = Math.Min(oldMem, minMem) maxMem = Math.Max(oldMem, maxMem) Console.WriteLine() For j = 1 To LoopMax Module1._i += 1 Dim ds As DataSet #If TYPED_DATASET = 1 Then ds = New DataSet1() If Cancel Then Exit While #Else _Log = " before New DataSet()" & vbCrLf ds = New DataSet() ds.EnforceConstraints = False For Module1._table = 1 To TableCount Dim tblName = "Table" & Module1._table.ToString("0000") Dim tbl As New DataTable(tblName) For Module1._column = 1 To ColumnCount Dim colName = "Column" & Module1._column.ToString("000") Dim col As New DataColumn(colName) tbl.Columns.Add(col) Next ds.Tables.Add(tbl) If Cancel Then Exit While Next ds.EnforceConstraints = True _Log &= " before Clear()" & vbCrLf #End If ds.Clear() Next Dim newMem = GC.GetTotalMemory(False) minMem = Math.Min(newMem, minMem) maxMem = Math.Max(newMem, maxMem) Console.WriteLine("使用容量 {0,-40}", String.Format("{0:#,0} => {1:#,0}", oldMem, newMem)) Console.WriteLine() Console.WriteLine("最低 {0,-15:#,0}", minMem) Console.WriteLine("最高 {0,-15:#,0}", maxMem) End While Console.SetCursorPosition(0, 10) Console.WriteLine(If(Cancel, "キャンセル", "ループ終了")) Console.WriteLine(GetLog()) Console.WriteLine("現在時刻 " & Now.ToString("yyyy/MM/dd HH:mm:ss.fffffff")) Loop While MsgBoxResult.Yes = MsgBox("もう一度最初から?", vbYesNo Or vbQuestion)
Console.SetCursorPosition(0, 21) Console.WriteLine("Hit Any Key...") Console.ReadKey() End Sub
End Module
|