Why are compiled Java class files smaller than C compiled files?

后端 未结 9 1432
被撕碎了的回忆
被撕碎了的回忆 2020-12-16 17:16

I would like to know why the .o file that we get from compiling a .c file that prints \"Hello, World!\" is larger than a Java .class file that also prints \"Hello, World!\"?

相关标签:
9条回答
  • 2020-12-16 17:43

    Most (as much as 90% for simple functions) of an ELF-format .o file is junk. For a .o file containing a single empty function body, you can expect a size breakdown like:

    • 1% code
    • 9% symbol and relocation table (essential for linking)
    • 90% header overhead, useless version/vendor notes stored by the compiler and/or assembler, etc.

    If you want to see the real size of compiled C code, use the size command.

    0 讨论(0)
  • 2020-12-16 17:43

    A class file is Java byte code .

    It is most likely smaller since C/C++ libraries and operating system libraries are linked to the object code the C++ compiler produces to finally make an executable binary.

    Simply put, it is like comparing Java byte code to object code produced by a C compiler before it is linked to create a binary. The difference is the fact that a JVM interprets the Java byte code to properly do what the program is meant to do whereas C requires information from the operating system since the operating system functions as the interpreter.

    Also in C Every symbol (functions etc.) you reference from an external library at least once in one of the object files is imported. If you're using it in multiple object files, it's still imported just once. There are two ways this "importing" can happen. With static linking, the actual code for a function is copied into the executable. This increases file size but has the advantage that no external libraries (.dll/.so files) are needed. With dynamic linking this doesn't happen, but as a result your program requires additional libraries to run.

    In Java, everything is "linked" dynamically, so to speak.

    0 讨论(0)
  • 2020-12-16 17:45

    A few potential reasons:

    • The Java class file does not include initialization code at all. It just has your one class and one function in it - very small indeed. In comparison, the C program has some degree of statically-linked initialization code, and possibly DLL thunks.
    • The C program may also have sections aligned to page boundaries - this would add a minimum of 4kb to the program size just like that, in order to ensure the code segment starts on a page boundary.
    0 讨论(0)
  • 2020-12-16 17:50

    One of the key reasons for differences in the sizes of .o and .class files is that Java bytecodes are a bit higher-level than machine instructions. Not hugely higher-level, of course – it's still pretty low-level stuff – but that will make a difference because it effectively acts to compress the whole program. (Both C and Java code can have startup code in there.)

    Another difference is that Java class files often represent relatively small pieces of functionality. While it is possible to have C object files that map to even smaller pieces, it's often more common to put more (related) functionality in a single file. The differences in scoping rules can also act to emphasize this (C doesn't really have anything that corresponds to module-level scope, but it does have file-level scope instead; Java's package scope works across multiple class files). You get a better metric if you compare the size of a whole program.

    In terms of "linked" sizes, Java executable JAR files tend to be smaller (for a given level of functionality) because they're delivered compressed. It's relatively rare to deliver C programs in compressed form. (There's also differences in the size of the standard library, but they might as well be a wash because C programs can count on libraries other than libc being present, and Java programs have access to a huge standard library. Picking apart who has the advantage is awkward.)

    Then, there's also the question of debugging information. In particular, if you compile a C program with debugging on that does IO, you'll get lots of information about types in the standard library included, just because it's a bit too awkward to filter it out. The Java code will only have debugging information about the actual compiled code because it can count on relevant information being available in the object file. Does this change the actual size of the code? No. But it can have a big impact on the file sizes.

    Overall, I'd guess that it's hard to compare the sizes of C and Java programs. Or rather, you can compare them and easily learn nothing much useful.

    0 讨论(0)
  • 2020-12-16 17:52

    Java is compiled into a machine independent language. This means that after it is compiled it is then translated at run-time by the Java Virtual Machine (JVM). C is compiled to machine instructions and is therefore all of the binary for the program to run on the target machine.

    Because Java is compiled to a machine independent language, the specific details for a particular machine are handled by the JVM. (i.e. C has machine specific overhead)

    That is how I think about it anyway :-)

    0 讨论(0)
  • 2020-12-16 17:55

    The main cause of difference in size in this case is difference in file formats. For such a small program format of the ELF (.o) file introduces serious overhead in terms of space.

    For example, my sample .o file of the "Hello, world" program takes 864 bytes. It consists of (explored with readelf command):

    • 52 bytes of file header
    • 440 bytes of section headers (40 bytes x 11 sections)
    • 81 bytes of section names
    • 160 bytes of symbol table
    • 43 bytes of code
    • 14 bytes of data (Hello, world\n\0)
    • etc

    .class file of the similar program takes only 415 bytes, despite the fact that it contains more symbol names and these names are long. It consists of (explored with Java Class Viewer):

    • 289 bytes of constant pool (includes constants, symbol names, etc)
    • 94 bytes of method table (code)
    • 8 bytes of attribute table (source file name reference)
    • 24 bytes of fixed-size headers

    See also:

    • Executable and Linkable Format
    • Java class file
    • Java Class Viewer
    0 讨论(0)
提交回复
热议问题