石野光仁 Blog

開発、C#、ASP.NET、アイライトの活動について、いろいろ

AILight Banner
AILight Blog

プロフィール

石野光仁 Blog

目次

Blog 利用状況

記事分類

過去の記事

タグ

.NET 1.1の頃に走りきれなかったコードを 2.0で通してみる

遠い昔に、GDNJで「IDisposable/Dispose/using に関して」という
スレッドがありました。

この中で、Disposeの話から、GCの話しに行き、面白いコードが
発見されました。 (発見なのか?)
NyaRuRuさんの書き込みにあったコードです。
コメントには、こんな風にかかれています。

  GCがいつ動くか分からないという例であれば,
  
うちの環境では以下のコードで十分です.
  メモリは1.5GBほど積んでいますが,i == 11 でばっち
 
 り"System.OutOfMemoryException"を起こします.

ということで、このコードを2.0の環境で動かしたらどうなるかと
思いまして、実験してみました。 
(コードは、フォームのボタンを押したら、実行するように修正)
私の環境は、CPU:P4-2.26GHz Mem:512MB OS:Windows XP-SP2

結果から話しますと、問題なく走り抜けます。
ということで、この辺の動作が、1.1の頃から比べて変わったことがわかります。

前回同様、このままでは面白くないので、追加でテストをしてみました。
面白い現象がいくつかありますので、あげておきます。

まず、Releseモードで動かすと、メモリの使用量は殆ど変わりません。
Debugモードで動かすと、全体のメモリ使用量が、713MBから989MBへ
増えます。ただし、プロセスでメモリ使用量を見ると増えていませんね。

ということで、プログラムをちょっと修正して、確保したメモリに
値をいれてみました。 そうするとReleseモードもDebugモードと
同様の動きになりますね。メモリを利用した時点で、OS側のメモリが
消費されると言うことでしょう。
ただ、プロセス単位では、メモリの消費量が増えないのが気になります。
まぁ、これがどういうことなのか? といわれると
Windowsのメモリ管理に関しては、それほど詳しくないので
わかりません。
OS全体では、消費されたメモリが、プロセス単位では消費されないのは
どうして? と次にバトンをまわして、今回はこれで終了

class Class1
{
    static void Main(string[] args)
    {
        int i = 0;
        try
        {
            for (i=0; i < 128; ++i)
            {
                byte[] buffer = new Byte[ 1024*1024*128 ];
            }
            System.Diagnostics.Debug.WriteLine("完走!");
        }
        catch
        {
            System.Diagnostics.Debug.WriteLine(i + " 回目でストップ");
        }
    }
}

投稿日時 : 2005年6月30日 16:53


コメントを追加

#  re: .NET 1.1の頃に走りきれなかったコードを 2.0で通してみる 2005年6月30日 17:44 菊池

>メモリを利用した時点で、OS側のメモリが
>消費されると言うことでしょう。

ちがうと思うな new したバッファを結局使ってないことがコンパイラかJITにばれてnew そのものが最適化で除去されたんだと思うよ。

#  re: .NET 1.1の頃に走りきれなかったコードを 2.0で通してみる 2005年6月30日 20:33 渋木宏明(ひどり)

>メモリを利用した時点で、OS側のメモリが
>消費されると言うことでしょう。

確保しただけだとアドレス空間しか消費してなくて、読み書きした時点でページが割り当てられてるのかな?

#  re: .NET 1.1の頃に走りきれなかったコードを 2.0で通してみる 2005年6月30日 20:34 渋木宏明(ひどり)

あ、最適化で除去か (^^;

#  re: .NET 1.1の頃に走りきれなかったコードを 2.0で通してみる 2005年7月6日 2:31 syar

new の前にGC::Collectを入れると落ち着きましたが、どうでしょうか?
タイトル
名前
URL
コメント