<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>技術(.NET 1.1)</title><link>http://www.kslaboratory.com/blog/category/14.aspx</link><description>.Net Frameworkに関するPOST</description><managingEditor>Kazuaki Shigetou</managingEditor><dc:language>ja-JP</dc:language><generator>.Text Version 0.95.2004.102</generator><item><dc:creator>Kazuaki Shigetou</dc:creator><title>[.NET]DataSet内の検索とパフォーマンス</title><link>http://www.kslaboratory.com/blog/archive/2007/11/20/279.aspx</link><pubDate>Tue, 20 Nov 2007 15:05:00 GMT</pubDate><guid>http://www.kslaboratory.com/blog/archive/2007/11/20/279.aspx</guid><wfw:comment>http://www.kslaboratory.com/blog/comments/279.aspx</wfw:comment><comments>http://www.kslaboratory.com/blog/archive/2007/11/20/279.aspx#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.kslaboratory.com/blog/comments/commentRss/279.aspx</wfw:commentRss><trackback:ping>http://www.kslaboratory.com/blog/services/trackbacks/279.aspx</trackback:ping><description>&lt;P&gt;DataSetの検索には以下を考慮する。&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;主キーを条件に検索する場合はDataTableのRowsプロパティのFindメソッドを使う。&lt;/LI&gt;
&lt;LI&gt;Selectメソッドはインデックスを利用しないので極力使わない。&lt;/LI&gt;
&lt;LI&gt;同じフィールドに対しての検索を繰り返す場合はDataViewを生成して（インデックスを生成して）FindまたはFindRowsメソッドを利用する。ただし、試行回数が少ない場合はインデックス生成のコストのほうが高くつくため、DataTableのSelectメソッドを利用する。&lt;/LI&gt;&lt;/UL&gt;&lt;img src ="http://www.kslaboratory.com/blog/aggbug/279.aspx" width = "1" height = "1" /&gt;</description></item><item><dc:creator>Kazuaki Shigetou</dc:creator><title>[.NET]DateTime.Nowの精度についてメモ</title><link>http://www.kslaboratory.com/blog/archive/2007/11/20/278.aspx</link><pubDate>Tue, 20 Nov 2007 14:49:00 GMT</pubDate><guid>http://www.kslaboratory.com/blog/archive/2007/11/20/278.aspx</guid><wfw:comment>http://www.kslaboratory.com/blog/comments/278.aspx</wfw:comment><comments>http://www.kslaboratory.com/blog/archive/2007/11/20/278.aspx#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.kslaboratory.com/blog/comments/commentRss/278.aspx</wfw:commentRss><trackback:ping>http://www.kslaboratory.com/blog/services/trackbacks/278.aspx</trackback:ping><description>.NET で現在の日付と時刻を取得するにはDateTime構造体（System名前空間）のオブジェクトのNowプロパティを呼び出す。&lt;BR&gt;ただ少し注意が必要なのは、このDateTime.Nowの精度は10ms前後らしく、10ms前後に一度DateTime.Nowの返す値が変わる&lt;BR&gt;&lt;BR&gt;だから以下のような処理をしたら、&lt;BR&gt;
&lt;TABLE style="TEXT-ALIGN: left" cellSpacing=0 cellPadding=0 border=1&gt;
&lt;TBODY&gt;
&lt;TR&gt;
&lt;TD style="BACKGROUND-COLOR: rgb(204,204,204)"&gt;static void Main(string[] args)&lt;BR&gt;{&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Console.WriteLine("start {0:yyyy/MM/dd HH:mm:ss.ffffff}", DateTime.Now);//①&lt;BR&gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Console.WriteLine(" なんか処理したよ");&lt;BR&gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Console.WriteLine("end&amp;nbsp;&amp;nbsp; {0:yyyy/MM/dd HH:mm:ss.ffffff}", DateTime.Now);//②&lt;BR&gt;}&lt;/TD&gt;&lt;/TR&gt;&lt;/TBODY&gt;&lt;/TABLE&gt;&lt;BR&gt;&lt;BR&gt;①～②間が0から10ms前後の場合だと同じ値が出力されることがあるわけで・・・。（マシンスペックや処理内容による）&lt;BR&gt;
&lt;TABLE style="COLOR: rgb(0,153,0); BACKGROUND-COLOR: rgb(0,0,0); TEXT-ALIGN: left" cellSpacing=0 cellPadding=0 border=1&gt;
&lt;TBODY&gt;
&lt;TR&gt;
&lt;TD&gt;start 2007/11/20 14:33:05.510467&lt;BR&gt;&amp;nbsp;なんか処理したよ&lt;BR&gt;end&amp;nbsp;&amp;nbsp; 2007/11/20 14:33:05.510467&lt;/TD&gt;&lt;/TR&gt;&lt;/TBODY&gt;&lt;/TABLE&gt;
&lt;P&gt;&lt;BR&gt;&lt;BR&gt;経過時間を正確に取りたい場合はSystem.Diagnostics.Stopwatch クラス（.NET Fx2.0の場合）を使うようにする。&lt;BR&gt;また、前回実行日時と今回実行日時を比較する場合なんかにDateTime.Nowで取得した値を使うのはNGなんだなぁ。&lt;BR&gt;&lt;/P&gt;&lt;img src ="http://www.kslaboratory.com/blog/aggbug/278.aspx" width = "1" height = "1" /&gt;</description></item><item><dc:creator>Kazuaki Shigetou</dc:creator><title>メモリリーク</title><link>http://www.kslaboratory.com/blog/archive/2006/12/03/151.aspx</link><pubDate>Sun, 03 Dec 2006 07:45:00 GMT</pubDate><guid>http://www.kslaboratory.com/blog/archive/2006/12/03/151.aspx</guid><wfw:comment>http://www.kslaboratory.com/blog/comments/151.aspx</wfw:comment><comments>http://www.kslaboratory.com/blog/archive/2006/12/03/151.aspx#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.kslaboratory.com/blog/comments/commentRss/151.aspx</wfw:commentRss><trackback:ping>http://www.kslaboratory.com/blog/services/trackbacks/151.aspx</trackback:ping><description>&lt;P&gt;「メモリリークだよ・・・」ということでヘルプに入りました。一応解決したのでメモメモ。&lt;/P&gt;
&lt;P&gt;　当該アプリは.NET Fx1.1、MTAのコンソールアプリケーション。メインスレッドが処理スレッド（System.Thread.Threading）をいくつか起動して、メインスレッド自体がスピンロックでポーリングして処理スレッドが終了するまで待機するというつくり。&lt;/P&gt;
&lt;P&gt;　症状を整理すると以下のとおり。&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;プロセス終了までメモリ使用量が増加し続ける 
&lt;LI&gt;特にGen 2のヒープメモリ使用量が右肩上がりに増える 
&lt;LI&gt;Gen 1とGen 0のヒープメモリは定期的に開放されているっぽい 
&lt;LI&gt;Gen 1とGen 0のGCは定期的に行われている 
&lt;LI&gt;Gen 2のGCが殆ど行われない （Gen0,Gen1に比べて少ないのは当然だが、異常に少なすぎる） 
&lt;LI&gt;シングルスレッドで処理した場合はメモリの増加は一定量を超えずGen 2のヒープも定期的に開放される&lt;/LI&gt;&lt;/UL&gt;
&lt;P&gt;　とりあえずソースコードを眺めた。構造はマルチスレッドのデザインパターンを適用した、シンプルでそれなりに考えられたものになっている。気になる点は下記3点。&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;スピンロックに再帰処理を利用している 
&lt;LI&gt;非同期デリゲートで起こしたスレッドで長時間処理を行う実装になっている 
&lt;LI&gt;BeginInvokeに対してEndInvokeを呼び出していない&lt;/LI&gt;&lt;/UL&gt;
&lt;P&gt;　んー、スピンロックを再帰処理で実現したらコールスタックには積まれる一方じゃないか・・・。&lt;/P&gt;
&lt;P&gt;　気になる点を一つずつ修正して検証をしてみたけど、症状は改善せず・・・。色々試しているうちにスピンロックの待機方法を変更してみた（Thread.Sleep→WaitHandle.WaitOne）。すると症状は嘘のように治り、リークが発生しなくなった。パフォーマンスモニタで計測してみるとGen 2 GCが理想的に行われるようになっていた。とりあえず問題は解決、Thread.SleepをWaitHandleを利用した待機に変更しただけなんだが・・・。&lt;/P&gt;
&lt;P&gt;　解決はしたものの、いまいち理屈が理解できていない。とりあえずThread.SleepがGCに何らかの影響を及ぼし、WaitHandle.WaitOneだと問題がないらしい（理屈は？？？）。※ちなみにThread.SpinWaitでも結果はThread.Sleepと同じ。&lt;/P&gt;
&lt;P&gt;　Microsoftが提供しているCLRのメモリ管理とGCの仕組みについてのドキュメントを再読したが、いまいち納得がいかず。おそらくGCのスレッドハイジャックの仕組みに何か悪影響を与えていたんだろうなぁ。まだまだ勉強の余地がありだ。三流エンジニアは日々これ精進っす&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;[今回の教訓]&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;　スピンロックでポーリングの仕組みをとる際は、Thread.SleepではなくWaitHandle.WaitXXXを利用する。そうしないとGCが正しく働かずメモリが開放されないかも・・・&lt;/STRONG&gt;
&lt;P&gt;
&lt;HR&gt;
&lt;/P&gt;
&lt;P&gt;&lt;/P&gt;
&lt;P&gt;[参考]&lt;/P&gt;
&lt;P&gt;ガベージコレクション入門: Microsoft .NET Framework の自動メモリ管理 Part II【&lt;A href="http://www.microsoft.com/japan/msdn/net/mag00/GCI2.aspx"&gt;http://www.microsoft.com/japan/msdn/net/mag00/GCI2.aspx&lt;/A&gt;】&lt;/P&gt;&lt;img src ="http://www.kslaboratory.com/blog/aggbug/151.aspx" width = "1" height = "1" /&gt;</description></item></channel></rss>