none
Vista環境とXP環境下のメモリ使用量が2倍も違う... RRS feed

  • 質問

  • C#でもともとXP環境でソフトを作っていて、Vistaでの動作チェックをしようと思い、Vistaで動作確認をしていると、XP環境下とVista環境下で、メモリ使用量に違いがあることがわかりました。

    メモリ使用量の確認のために利用しているのはOS標準のタスクマネージャーです。
    ソフトはMDIで、あるデータを処理するソフトです。

    XPでは、データをロードし処理するときに、メモリ使用量が120MBに達しますが、
    Vistaでは、同じ処理をしていても、メモリ使用量が65MB程度と、約1/2になるのです。

    Vistaでのメモリ管理がよくなったと簡単に理解してもいいのでしょうか?

    XPで作成しているときに、120MBものメモリ使用量は異常だと考え、メモリ負荷軽減のために自作クラスにはIDisposeを継承させDispose処理を実装させたり、usingやtry~finallyを活用して確実に解放されるようにしたり、さらに利用しなくなった変数はnullを代入するなどして、考えられることはすべてやりましたが、どうしても120MB以下に下げることができませんでした。

    ほとんど諦めていたのですが、今回Vistaで動作確認してみると、メモリ使用量が65MBと目指していた少ない使用量になったので、この差はどうして生まれるのだろうと疑問をもちました。

    ちなみに、GCの実行前の数字であっては比較の意味がないので、いずれのメモリ使用量もGC.Collect()で強制実行した後の数字です。それを行っても数MB程度しかかわりませんでしたが。

    全く同じソフトで同じ処理をさせて、なぜこのような差が生じるのでしょうか?

    ちなみに、XP環境(開発環境)は、SP2、.NET Framework 2.0、Visual Studio 2005、Norton Internet Security 2007、Pentium 4 4.8GHz程度、4GBを導入しています。またVista環境は、Ultimate、.NETはOS標準(おそらく3.0)、Visual Studio 2005、Norton Internet Security 2007、Pentium 4.2GHz、1GBを導入しています。

    気になる点は搭載しているメモリ量の違いと.NET Frameworkのバージョンの違い。でも.NET Framework 3.0は2.0+拡張機能なのでこれによるものではないような気もするのですが。どうなんでしょう。

    2007年3月11日 8:19

回答

すべての返信

  • というか、

    >メモリ負荷軽減のために自作クラスにはIDisposeを継承させDispose処理を実装させたり

    これはメモリ負荷うんぬん以前の問題。解放しなくちゃいけないアンマネージリソースがあるなら当然処理しなくちゃいけないことです。

    それでタスクマネージャのメモリ使用量はあてにならないって知ってますか?検索してみてください。

    OSが変わるとメモリの最適化の狙い目なんかも変わってきますし、あまり意味のある比較をしているとは思えません。

    >でも.NET Framework 3.0は2.0+拡張機能なのでこれによるものではないような気もするのですが。どうなんでしょう

    おっしゃるように.NET Framework はCLRのバージョンが2.0ですので、.NET Framework 2.0と同一です。

    2007年3月11日 11:51
  •  eika さんからの引用

    全く同じソフトで同じ処理をさせて、なぜこのような差が生じるのでしょうか?

    Vista ではタスクマネージャにデフォルトで表示される項目が変わったので,そのせいではないでしょうか?
    以前日記で書いたものですが,ご参考までに.

    タスクマネージャに表示されるメモリ使用量

    2007年3月11日 14:27
  • 物理メモリの搭載量が相当違うので、GC がマネージヒープの回収はしてもコンパクションを端折って、見かけ上のワーキングセットが大きいままなんて事もあるようなないような。
    2007年3月11日 15:40
  • みなさん、回答ありがとうございます。

    なるほど、表示される項目が変わったんですね。指摘されて、実際にXP機で確認したところ、仮想メモリサイズとVista機で表示されたメモリ使用量がほぼ同じように推移していました。原因がわかってすっきりです。

    また、NyaRuRuさんの記載されていたブログも読ませていただきました。

    「ある程度PCの知識はあるが Windowsの仮想メモリ機構に関する十分な知識はないユーザ(及び開発者)」が,タスクマネージャに表示される「メモリ使用量」に過剰反応してしまう」

    確かに、メモリ使用量を基準に嫌悪されることが多いです。(私もそう思ってました汗)
    以前、フリーソフトを公開していたのですが、メモリ使用量が多いと指摘されたことがありました。それ以降どうやったらメモリ使用量を抑えることができるのかといろいろ試したのですが、あまり効果がありませんでしたが...。「
    メモリの使用量の少なさ」=「よりよいプログラミング」と勝手に思い込んでいたのですが間違いということでしょうか。

    また、比較的簡単な処理をするソフトでも.NETで開発したWindowsアプリケーションの場合30~40MB以上になります。私のようなあまり詳しくない人が.NETでプログラミングをはじめたころに感じられた方もいらっしゃるかもしれませんが、自作したソフトが物理メモリが少ないPC(XPで256MB程度など)で他のソフトやOSのパフォーマンスを低下させる原因になるのではないかと思ってしまうことがあります。これは、プログラミングを適切に記述していればメモリの使用量の消費はそこまで神経質に気にしなくてもいいのでしょうか?

    2007年3月11日 16:54
  •  eika さんからの引用

    確かに、メモリ使用量を基準に嫌悪されることが多いです。(私もそう思ってました汗)
    以前、フリーソフトを公開していたのですが、メモリ使用量が多いと指摘されたことがありました。それ以降どうやったらメモリ使用量を抑えることができるのかといろいろ試したのですが、あまり効果がありませんでしたが...。「
    メモリの使用量の少なさ」=「よりよいプログラミング」と勝手に思い込んでいたのですが間違いということでしょうか。

    一般に「メモリ使用量の少ないアルゴリズム」は「優れたアルゴリズム」と言えると思うのですが,厄介なことにアルゴリズムの議論をするときの「メモリ使用量」とタスクマネージャに表示される「メモリ使用量」は,定義が異なるのです.
    そのため,タスクマネージャに表示される「メモリ使用量」を見ても,それが「メモリ使用量の多いアルゴリズム」なのか,「メモリ使用量の少ないアルゴリズム」なのか,きちんと判断することができません.従って,タスクマネージャの「メモリ使用量」からプログラムの良し悪しを議論すべきではない,と私は考えています.

     eika さんからの引用

    また、比較的簡単な処理をするソフトでも.NETで開発したWindowsアプリケーションの場合30~40MB以上になります。私のようなあまり詳しくない人が.NETでプログラミングをはじめたころに感じられた方もいらっしゃるかもしれませんが、自作したソフトが物理メモリが少ないPC(XPで256MB程度など)で他のソフトやOSのパフォーマンスを低下させる原因になるのではないかと思ってしまうことがあります。これは、プログラミングを適切に記述していればメモリの使用量の消費はそこまで神経質に気にしなくてもいいのでしょうか?

    先ほど述べたように,プログラムの簡単さ・複雑さとタスクマネージャに表示される「メモリ使用量」は単純には結びつきません.とはいえ,どうしても気になるという人はいるでしょうから,そういう場合は .NET 以外の方法で実装するか,SetProcessWorkingSetSize API を使用して無理やりタスクマネージャの「メモリ使用量」を少なく見せることなどの対策が考えられます.

    2007年3月11日 17:27
  • 丁寧な回答ありがとうございます。

    一般に「メモリ使用量の少ないアルゴリズム」は「優れたアルゴリズム」と言えると思うのですが,厄介なことにアルゴリズムの議論をするときの「メモリ使用量」とタスクマネージャに表示される「メモリ使用量」は,定義が異なるのです.

    とありますが、Process Explorerなどのツールを使うと、その判断に利用できる数字は現れるのでしょうか?

    SetProcessWorkingSetSize API を使用して無理やりタスクマネージャの「メモリ使用量」を少なく見せることなどの対策が考えられます.

    ブログを拝見させていただいた際に「MyTrimmer」というソースのサンプルをダウンロードして、リストから当該アプリケーションを選択後「Start Trimming」を実行したところ、一時的にWorking Setがかなり低い数字(400KB近く)になりましたが、すぐに徐々にその量は増えていき、やらない前よりはかなり軽減されてはいますが60~70MB程度になりました。通常ならこのとき「110MB」程度まで達していますのでかなり軽減はされています。この(徐々に増加する)挙動は問題ないですよね?それともプログラムに何かしら問題があるのでしょうか?

    また、SetProcessWorkingSetSize APIを活用する場合、自作アプリケーションに組み込んで利用するはずですが、これは初回起動時にだけ実行すべきでしょうか?それとも何度も呼び出しても構わないのでしょうか?

     

     

    2007年3月12日 5:26
  •  eika さんからの引用

    丁寧な回答ありがとうございます。

    一般に「メモリ使用量の少ないアルゴリズム」は「優れたアルゴリズム」と言えると思うのですが,厄介なことにアルゴリズムの議論をするときの「メモリ使用量」とタスクマネージャに表示される「メモリ使用量」は,定義が異なるのです.

    とありますが、Process Explorerなどのツールを使うと、その判断に利用できる数字は現れるのでしょうか?

    タスクマネージャに表示される「メモリ使用量」をはじめとして,判断に利用できる数字というのは多数あります.しかし,厳密にアルゴリズムのメモリ使用量と一致する数字というのはそもそも存在しません.多くの場合仮想メモリなど影響を受けたの仮想環境下で実行されますので,プログラミングしたとおりにハードウェアが動いているわけではないのです.
    結局のところ,Windows のメモリマネジメントの仕組みについて調べてください,という他ありません.

     eika さんからの引用

    とありますが、Process Explorerなどのツールを使うと、その判断に利用できる数字は現れるのでしょうか?

    SetProcessWorkingSetSize API を使用して無理やりタスクマネージャの「メモリ使用量」を少なく見せることなどの対策が考えられます.

    ブログを拝見させていただいた際に「MyTrimmer」というソースのサンプルをダウンロードして、リストから当該アプリケーションを選択後「Start Trimming」を実行したところ、一時的にWorking Setがかなり低い数字(400KB近く)になりましたが、すぐに徐々にその量は増えていき、やらない前よりはかなり軽減されてはいますが60~70MB程度になりました。通常ならこのとき「110MB」程度まで達していますのでかなり軽減はされています。この(徐々に増加する)挙動は問題ないですよね?それともプログラムに何かしら問題があるのでしょうか?

    また、SetProcessWorkingSetSize APIを活用する場合、自作アプリケーションに組み込んで利用するはずですが、これは初回起動時にだけ実行すべきでしょうか?それとも何度も呼び出しても構わないのでしょうか? 

    徐々に増加する挙動は,典型的なページフォルトによるワーキングセットの増加パターンですので,問題ないと思います.

    SetProcessWorkingSetSize をいつ,どのように呼ぶかですが,ケースバイケースです.そもそもこれは「メモリ使用量」を少なく見せる API ではなくて,明確にワーキングセットを縮小させる API なので,初回起動時だけに呼ぶか,何度も呼ぶかは本来利用者が分かっていて使うものです.そのため,あるアプリケーションで何度も呼び出して問題がないかどうかは一概には答えられません.

    なお,SetProcessWorkingSetSize を呼び出したからといってクラッシュするということはまずありません.基本的にはパフォーマンスに関する影響のみです.

    例えば Windows NT 4.0 ~ Windows Server 2003 では,アプリケーションのウィンドウを最小化するたびにそのアプリケーションに対してシステムが SetProcessWorkingSetSize を呼び出していたような挙動が見られました.この時に発生していた副作用を問題ないと思うのであれば,ウィンドウ最小化程度の頻度で呼び出すのは問題ないということになるかと思います.

    その副作用の1つとしては,『レスポンスチューニング』で書いたように,大量のヒープを消費するアプリケーションで,この挙動による意図しないページアウトがパフォーマンス問題を引き起こしていたという事例がおきています.そして Windows Vista では,ウィンドウ最小化で ワーキングセットの縮小はほとんど起きなくなったように見え,やはりこの挙動は現状のアプリケーション規模にあわなくなっていたのだろうと私は考えています.

    2007年3月18日 4:03