torutkのブログ

ソフトウェア・エンジニアのブログ

書籍購入(不本意ながらC#関連第1冊目)

The Root of .NET Framework

The Root of .NET Framework

開発言語選定の一環として、.NET Frameworkがどのような仕組みで動いているのか、を調べていましたが、インターネット上にもなかなか情報が少なく、C#プログラマに聞いても知らない人が多く(!)、そんなときに本屋さんで見つけた本です。CLRとはなにかやっと頭に入りました。クラスローダ、JITGCについても書かれています。

この手の実行基盤の話は、もう1冊プログラミングMS .NET FRAMEWORK 第2版 (マイクロソフト公式解説書)が評判よさそうなのですが、ちょっと高価ですね。

JITコンパイラ

上記書籍(前者)によれば、.NET Frameworkではメソッド単位でCILからネイティブコードにコンパイルされ、そのタイミングは最初にメソッドが呼ばれるときです。メソッド単位でコンパイルされるということは、JavaのHotSpot VMコンパイラと比較した場合、定性的には

  • パフォーマンスの最適化が限定されそうだ
  • アプリケーションの起動〜初期化処理に時間がかかりそうだ
    • Javaはメソッドが一定回数呼ばれてからネイティブコードにコンパイルされる

という違いがありそうです。実際には定量的に比較しないといけないのですが、これはかなり難しいです。

.NET Frameworkアプリケーションは、起動に時間がかかるという問題もちらほら見かけます。ngenすればよいという単純な回答もありますが、ngenによって起動時に読み込むファイルサイズが増えるので必ずしも早くならないという議論もあります。またプログラムの配布も大変になるようで、一筋縄ではいかない課題のようです。

http://msdn.microsoft.com/ja-jp/magazine/cc163655%28en-us%29.aspx

ガベージコレクタ

.NET Frameworkは世代別GCを装備しています。ただ、それはJavaとは随分違う説明にちょっと驚きました。やはり、ちゃんと深く把握しないで字面だけから「世代別GC、あっ、Javaと同じ方式だね」と理解しては間違えのもとですね。
上記書籍(前者)によれば、世代別ですが、回収されないものはCompactionされるようです。また、サイズの大きなオブジェクトは、世代別GC対象ではなく別領域で管理され、GCの方式は、世代なしかつCompactionなし(回収されたオブジェクトの領域は空きとなる)のようです。長時間稼動するシステムではヒープ断片化の懸念があるかもしれません。
.NET Frameworkは、GC中は他のプログラムが停止する("Stop the world")という課題もあります。

JavaGCにも当初その課題がありました。複数のガベージコレクタが用意されており、選択可能なGCの中には"Stop the world"時間を短くするための方式も含まれています。が、CPUが少ないと返って遅くなるといった特性もあり、万能の1つの方法はありません。
どれが適するかを判断できるために、ある程度GCの方式とその得失を理解しておく必要があります。
http://java.sun.com/javase/technologies/hotspot/gc/gc_tuning_6.html

.NET Framework 4.0でGCに変更があるか調べると・・・

上記を書きながら、.NET Framework 4.0でGCが追加・改善されていないか念のためさっと調べると、
http://blogs.msdn.com/ukadc/archive/2009/10/13/background-and-foreground-gc-in-net-4.aspx
こんな文書が出てきました。
この記事には、既に.NET Frameworkにも並列GCが入っているという記述もあり、再確認が必要かもしれません。

技術を比較するということは

設計には、複数考えられる候補から、トレードオフしてそのコンテクストにおいて最適なものを選択するという局面があります。要素技術の選択においては、候補の技術すべてに精通している設計者はなかなかいません。

が、時間は有限の中で最適な選定ができるための情報をいかに収集分析整理するかが課題です。これはかなり厳しい作業です。なので、安直に自分の知っている技術を選んでしまったり、検討なしに前例踏襲してしまうという過ちを犯してしまうのかなと思います。その場は楽ですから・・・。