none
constとstaticと参照設定とメモリ使用量 RRS feed

  • 質問

  • 妙な件名ですが、宜しくお願いします。

     

    次の様なEXEが1つ、DLLが2つがあります。

     

    App.exe

        public partial class Form1 : Form
        {
            private void button1_Click(object sender, EventArgs e)
            {
                MyLib.MessageShow();
            }
        }

    MyLib.dll

        public class MyLib
        {
            public static void MessageShow()
            {
                MessageBox.Show(MyMsg.MSGID1, "", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
            }
        }

    MyMsg.dll

        public class MyMsg
        {
            public const string MSGID1 = "メッセージです。";
        }

    それぞれ、App.exe -> MyLib.dll -> MyMsg.dll を参照(参照設定で)しています。

     

    それぞれのプロジェクトをコンパイル後、MSGID1の内容を書き換え、MyMsg.dllのみコンパイルし

    App.exeを実行したところ、書き換え前のメッセージ内容でMessageBoxが表示されました。

     

    それで、質問1。

    ---------------------------------------

    MSGID1はconst宣言なので、MyLib.dllコンパイル時、MyMsg.MSGID1がその時点での文字列に

    置き換えられてコンパイルされるので、その後、MSGID1が変更されても(MyMsg.dllが再コンパイル

    されても)MyLib.MessageShowメソッドは、変更前のメッセージでMessageBoxを表示してしまう

    ---------------------------------------

    で、合っていますでしょうか?

     

    その後、const宣言からstatic宣言に変更しました。

            public static readonly string MSGID1 = "メッセージです。";

    すると、MyMsg.dllのコンパイルのみで、即座に新しいメッセージ内容でMessageBoxが表示

    される様になりました。

     

    それで、質問2

    ---------------------------------------

    static宣言なので、全てメモリ上に展開されるので、その分、メモリ使用量は増える

    ---------------------------------------

    んでしょうか?

     

    メッセージは500程度なのですが、テスト的に単純はWindowsアプリで、static宣言がない

    ものと、static宣言のあるものとで比較してみたんですが、殆ど変わらないのですが。

    というか、起動のたびに微妙にメモリ量が変化しているような。ちなみに、タスクマネージャーでの

    参照です。

     

    皆様、ご教授願えませんでしょうか。

    宜しくお願い致します。

     

    2008年4月25日 4:01

回答

  • > 質問1
    はい、合ってます。コンパイル時に直接埋め込まれ、実行時には定数を参照しません。

    質問2
    static フィールドにしなくともどのみちメモリ上に確保されます。
    メモリ使用量の違いはありません。
    2008年4月25日 5:36
  •  よこけん さんからの引用
    > 質問1
    はい、合ってます。コンパイル時に直接埋め込まれ、実行時には定数を参照しません。

     

    付加情報として、情報元を書いておきます。

    http://msdn.microsoft.com/library/ja/default.asp?url=/library/ja/csref/html/vclrfConstPG.asp

     

    C# プログラマーズ リファレンス の const の説明に「定数式は、コンパイル時にすべて評価されます。」の記述があります。

    2008年4月25日 8:29
  •  @ぶるーの さんからの引用

    MSGID1はconst宣言なので、MyLib.dllコンパイル時、MyMsg.MSGID1がその時点での文字列に置き換えられてコンパイルされるので、その後、MSGID1が変更されても(MyMsg.dllが再コンパイルされても)MyLib.MessageShowメソッドは、変更前のメッセージでMessageBoxを表示してしまう


    それでいいと思います。
    ただ、アセンブリをまたがった参照で実装しているものはないと思いますが、conststatic readonly にしても、同じ動作をするような最適化は許されていると思います。

     @ぶるーの さんからの引用

    static 宣言なので、全てメモリ上に展開されるので、その分、メモリ使用量は増える

    最適化をしない場合、

    const の場合、MSGID1 を使用している場所ごとに MSGID1 のコピーが生成されますが、

    static の場合、MSGID1 を参照するようにコンパイルされます。

    つまり、const の方がメモリ使用量が増える可能性があります。

    2008年4月25日 15:46

すべての返信

  • > 質問1
    はい、合ってます。コンパイル時に直接埋め込まれ、実行時には定数を参照しません。

    質問2
    static フィールドにしなくともどのみちメモリ上に確保されます。
    メモリ使用量の違いはありません。
    2008年4月25日 5:36
  •  よこけん さんからの引用
    > 質問1
    はい、合ってます。コンパイル時に直接埋め込まれ、実行時には定数を参照しません。

     

    付加情報として、情報元を書いておきます。

    http://msdn.microsoft.com/library/ja/default.asp?url=/library/ja/csref/html/vclrfConstPG.asp

     

    C# プログラマーズ リファレンス の const の説明に「定数式は、コンパイル時にすべて評価されます。」の記述があります。

    2008年4月25日 8:29
  •  @ぶるーの さんからの引用

    MSGID1はconst宣言なので、MyLib.dllコンパイル時、MyMsg.MSGID1がその時点での文字列に置き換えられてコンパイルされるので、その後、MSGID1が変更されても(MyMsg.dllが再コンパイルされても)MyLib.MessageShowメソッドは、変更前のメッセージでMessageBoxを表示してしまう


    それでいいと思います。
    ただ、アセンブリをまたがった参照で実装しているものはないと思いますが、conststatic readonly にしても、同じ動作をするような最適化は許されていると思います。

     @ぶるーの さんからの引用

    static 宣言なので、全てメモリ上に展開されるので、その分、メモリ使用量は増える

    最適化をしない場合、

    const の場合、MSGID1 を使用している場所ごとに MSGID1 のコピーが生成されますが、

    static の場合、MSGID1 を参照するようにコンパイルされます。

    つまり、const の方がメモリ使用量が増える可能性があります。

    2008年4月25日 15:46
  • よこけんさん、FC-Shiroさん、Kazuya Ujiharaさん、回答ありがとうございます。

     

    大変参考になりました。

     

    ありがとうございました。

     

    2008年4月28日 23:40