Unless you consider that basic support services are what the Java runtime should be providing on its own. Fundamentally, a command line Hello world should only take a few dozen bytes of bytecode.
Now all engineers are "angry" :) :) :) after seeing the same process spawned multiple times, and taking lots of gigabytes!!! (hehee)... I simply don't care and love the Slack app! (Teams is also nice looking, and Visual Studio Code rocks)
Of course there are far smaller libc implementations, but they may be missing functionality.
[1] Unless, of course you require an installation of Java... which would kind of go against the premise of this whole exercise.
Note, this on 32 bit arm, size might differ on different arches, all I have access to off the cuff:
# printf '#include <stdio.h>\n int main(int argc, char**argv) { puts("hi"); }' > /tmp/hi.c
# make /tmp/hi
cc -c -o /tmp/hi.o /tmp/hi.c
cc /tmp/hi.o -o /tmp/hi
# du -hs /tmp/hi
12.0K /tmp/hi
# ldd /tmp/hi
/lib/ld-musl-armhf.so.1 (0x7f5af000)
libc.musl-armhf.so.1 => /lib/ld-musl-armhf.so.1 (0x7f5af000)
# strip /tmp/hi
# du -hs /tmp/hi
8.0K /tmp/hi
# rm /tmp/hi
# make LDFLAGS=-static /tmp/hi
cc -static /tmp/hi.o -o /tmp/hi
# du -hs /tmp/hi
92.0K /tmp/hi
# ldd /tmp/hi
ldd (0x7f5e3000)
# file /tmp/hi
/tmp/hi: ELF 32-bit LSB shared object, ARM, EABI5 version 1 (SYSV), dynamically linked, with debug_info, not stripped
ungh, go home ldd and file, you're both drunk and dead to me right now: # objdump -p /tmp/hi
/tmp/hi: file format elf32-littlearm
Program Header:
LOAD off 0x00000000 vaddr 0x00000000 paddr 0x00000000 align 2**16
filesz 0x00001f68 memsz 0x00001f68 flags r-x
LOAD off 0x00002ea4 vaddr 0x00012ea4 paddr 0x00012ea4 align 2**16
filesz 0x00000204 memsz 0x00000798 flags rw-
DYNAMIC off 0x00002eb4 vaddr 0x00012eb4 paddr 0x00012eb4 align 2**2
filesz 0x000000e0 memsz 0x000000e0 flags rw-
STACK off 0x00000000 vaddr 0x00000000 paddr 0x00000000 align 2**4
filesz 0x00000000 memsz 0x00000000 flags rw-
RELRO off 0x00002ea4 vaddr 0x00012ea4 paddr 0x00012ea4 align 2**0
filesz 0x0000015c memsz 0x0000015c flags r--
Dynamic Section:
SYMBOLIC 0x00000000
INIT 0x00000468
FINI 0x00001f38
INIT_ARRAY 0x00012ea4
INIT_ARRAYSZ 0x00000004
FINI_ARRAY 0x00012ea8
FINI_ARRAYSZ 0x00000004
GNU_HASH 0x000000d4
STRTAB 0x00000250
SYMTAB 0x00000120
STRSZ 0x000000ee
SYMENT 0x00000010
DEBUG 0x00000000
PLTGOT 0x00012f94
PLTRELSZ 0x00000018
PLTREL 0x00000011
JMPREL 0x00000450
REL 0x00000340
RELSZ 0x00000110
RELENT 0x00000008
BIND_NOW 0x00000000
FLAGS_1 0x08000001
RELCOUNT 0x0000001c
private flags = 5000400: [Version5 EABI] [hard-float ABI]
Note no NEEDED section, so we're indeed fully static. # strip /tmp/hi
# du -hs /tmp/hi
16.0K /tmp/hi
16K for a fully static hello world sounds pretty decent to me vs 8k for dynamic. Will be faster than involving ld.so as well. I could probably improve that further, but I'm not about to golf this tonight.Even if you don't buy that reasoning, it's just not very common to use non-glibc on most common distros.
... and honestly, I should probably just have been more explicit about the absurdity of comparing "hello world". That would sort of agree with the OP's post, but not for the same reason. I think reasons are important.
[1] ... but then you end up with discussions about the importance of locales, nsswitch, etc. etc. Even though I didn't bring it up, it necessitated this footnote. You see what I mean?
isn't this only true for the first time a function is used?
once all of the linking is done, the GOT will just contain the address of the function and it's just as if it were linked statically, right?
Yes, but it will happen each time the program loads, which means your LD_* variables will get parsed/iterated over. Statically linking stuff in can help if you have a program that needs to be exec()'d in a loop. While it'll probably only shave off 0.001 seconds per exec() call it can add up, more so if you have LD_LIBRARY_PATH set to look on some slow storage like nfs.
But its a bit of a hyper optimization at that point. I've used this to really annoy a c++ developer saying c++ was faster than c. Evil trick on my part but my euler solutions were always faster. >.<
That said I really need to get back to debugging the segfault in building ghc 8.2.2 on armhf in the ghc rts. But its gotten me going through everything but ghc and whatnot. Annoying when things worked before and don't now. Even weirder that only the final stage build is at issue, the other two are fine.
you only pay for what you use if you dynamically link it.
https://www.gnostice.com/nl_article.asp?id=225
The difference in abstraction level is amazing.