3

重複の可能性:
コンパイルされたJavaクラスファイルがCコンパイルされたファイルよりも小さいのはなぜですか?

好奇心から、C、C ++、Javaで「HelloWorlds」をコンパイルしました。

Javaクラスファイルは、ランタイムがバイナリに含まれていないため、私が理解している423Bで非常に無駄がありません。

ただし、CおよびC++のものは8.5Kおよび9.2Kです。

なぜそんなに大きいのですか?stdioまたはiostreamは動的にリンクされており、実行可能ファイルのサイズに追加されないと常に想定していました。

では、すべてのキロバイトはどこから来るのでしょうか?hexdumpを見ると、多くのパディングがあることがわかります。パフォーマンス上の理由から推測できます。なぜバイナリ形式がそのように編成されているのですか?


pmgのリンクはとても役に立ちます!

パディングに関しては、プログラムのセグメントを仮想メモリのページ境界(4096バイト)に揃えることで、少なくとも8192バイトになることがわかりました。

mach-oバイナリ形式について(OS XおよびiOS用)

最高のパフォーマンスを得るには、セグメントを仮想メモリのページ境界(PowerPCおよびx86プロセッサの場合は4096バイト)に揃える必要があります。セグメントのサイズを計算するには、各セクションのサイズを合計してから、その合計を次の仮想メモリページの境界(4096バイトまたは4キロバイト)に切り上げます。このアルゴリズムを使用すると、セグメントの最小サイズは4キロバイトになり、その後は4キロバイト単位でサイズが決定されます。

引用http://developer.apple.com/library/mac/#documentation/DeveloperTools/Conceptual/MachORuntime/Reference/reference.html

次回質問する前に調査します;)

4

4 に答える 4

5

これはあなたが何を測定しているのかという問題です。実行可能ファイルの生のサイズの場合、これにはのコード以外にも多くの内容が含まれていますmain()

ここでは共有ダイナミックライブラリを使用しているため、シンボルテーブル、グローバルオフセットテーブル、リンク先の共有ライブラリの説明などのハウスキーピングデータによって、サイズの大部分が考慮されます。共有ライブラリ自体はバイナリに含まれていません。

iostreamライブラリはかなり大きく、静的な初期化子もあります。たとえば、、、およびオブジェクトを初期cout化します。これは、オブジェクトファイルに含まれている必要があるもう1つのものです。cerrcin

実際には、アプリケーションの実行時に、余分なサイズのほとんどはメモリに常駐しません。

于 2012-08-05T09:08:19.457 に答える
2

C&C ++は、完全なスタンドアロンプ​​ログラムです。Javaは単なるコアコードであり、Javaを実行するには別のプログラムが必要です。

小さなhelloworldは、bashスクリプト(実行するために別のプログラムも必要とするもの)を使用することです。

echo Hello World

改行で合計17バイト。

于 2012-08-05T08:53:39.650 に答える
1

1つの要因は

#include <iostream>

これにより、多くの標準ライブラリがプログラムにリンクされます。ただし、心配する必要はありません。これは単なる初期オーバーヘッドであり、プログラムの複雑さやコードの長さによって増加することはありません。いずれの場合も、 UPXを使用してみてください。

于 2012-08-05T08:45:42.683 に答える
1

stdlibが含まれているためです。-nostdlibを使用してみてください

于 2012-08-05T08:35:50.167 に答える