Executable size?

901 views
Skip to first unread message

imabuddha

unread,
Nov 11, 2009, 2:44:37 AM11/11/09
to golang-nuts
I built a simple "Hello world" program in Go on darwin/amd64 and was
surprised to see the executable size was 638595 bytes. After finding
the -s linker switch to strip symbol tables the file is still 367064
bytes!

Am I missing something or is this the minimum size of a Go executable?

Russ Cox

unread,
Nov 11, 2009, 3:23:53 AM11/11/09
to imabuddha, golang-nuts

It is admitted a large binary, but hello world is not
a simple program: it pulls in the fmt library, which can
print many more interesting things than hello world,
and that in turn pulls in the reflection library, and the
dynamic type support, and the garbage collector,
and so on. It's a non-trivial amount of code. It's not
like printing hello world twice doubles the size of
the binary.

For what it's worth, a completely non-scientific
comparison:

; cat >x.c
#include <stdio.h>

int main(void) {
printf("hello, world\n");
return 0;
}
; gcc -static x.c
; ls -l a.out
-rwxr-x--- 1 rsc eng 665642 Nov 11 00:19 a.out
; size a.out
text data bss dec hex filename
573031 3424 12296 588751 8fbcf a.out
;

; cat >x.go
package main

import "fmt"

func main() {
fmt.Printf("hello, world\n");
}
; 6g x.go
; 6l x.6
; ls -l 6.out
-rwxr-x--- 1 rsc eng 634803 Nov 11 00:19 6.out
; size 6.out
text data bss dec hex filename
136145 225832 2180280 2542257 26cab1 6.out
;

Russ

imabuddha

unread,
Nov 11, 2009, 3:35:25 AM11/11/09
to golang-nuts
Thanks for the quick reply. Since the libs are being statically
linked the executable file size does make sense.

Jens Alfke

unread,
Nov 11, 2009, 12:10:55 PM11/11/09
to r...@golang.org, imabuddha, golang-nuts

On Nov 11, 2009, at 12:23 AM, Russ Cox wrote:

> It is admitted a large binary, but hello world is not
> a simple program: it pulls in the fmt library, which can
> print many more interesting things than hello world,
> and that in turn pulls in the reflection library, and the
> dynamic type support, and the garbage collector,
> and so on. It's a non-trivial amount of code.

Is there a plan to support shared/dynamic libraries? Sounds like that would be a huge help for executable size, which in turn would lower the memory footprint when running multiple Go processes.

—Jens

Ian Lance Taylor

unread,
Nov 12, 2009, 1:14:48 AM11/12/09
to Jens Alfke, r...@golang.org, imabuddha, golang-nuts
There is no particular plan at present. It could happen.

Ian

Jessta

unread,
Nov 12, 2009, 1:51:39 AM11/12/09
to Jens Alfke, golang-nuts
On 12/11/2009, Jens Alfke <je...@mooseyard.com> wrote:
> Is there a plan to support shared/dynamic libraries? Sounds like that would
> be a huge help for executable size, which in turn would lower the memory
> footprint when running multiple Go processes.
>

From what I've read and seen static linking a lot of the time results
in a much smaller footprint as libraries usually contain a lot of
rarely used code that has to be in memory anyway just in case an
unknown program actually wants to use it. Ever used a Gnome program on
KDE? wow, it's madness! Every tried to run a 5 year old binary on a
new linux distro? gah, incompatible shared library version ey?

You're more likely to be running a Go process, a few C processes and
something written in python, ruby,java etc. than you are to be running
enough Go processes with enough overlapping functionality to warrant
the added complexity of a shared library.

- Jessta
--
=====================
http://jessta.id.au

Jens Alfke

unread,
Nov 12, 2009, 2:25:06 AM11/12/09
to Jessta, golang-nuts

On Nov 11, 2009, at 10:51 PM, Jessta wrote:

> From what I've read and seen static linking a lot of the time results
> in a much smaller footprint as libraries usually contain a lot of
> rarely used code that has to be in memory anyway just in case an
> unknown program actually wants to use it.

No; that's not accurate at all. Shared libraries get mapped into the process's address space, but (a) pages are only loaded into RAM when the code in them is executed, and (b) the pages are shared by all processes using the library.

In other words, if no one is using a particular function, it's probably not in RAM (unless it shares a page with a function that is.) And if several processes are using the function, there's only one copy of it in RAM.

I can't speak for Linux, but on Mac OS X nearly everything is a shared library.

(This is heading off-topic; reply directly if you want to argue with me ;)

—Jens

Reply all
Reply to author
Forward
Message has been deleted
0 new messages