원본 소스 코드
package main
import "fmt"
func main() {
fmt.Println("Hello world!")
}$ go version
go version go1.13 linux/amd64
$ export CGO_ENABLED=0
$ go build; stat -c %s helloworld
2012745바이너리 파일 크기: 2012745
간단한 방법
-ldflags에 대한 자세한 설명은 프로젝트 루트에서 go build -ldflags -help를 실행하여 확인할 수 있습니다.-gcflags에 대한 자세한 설명은 프로젝트 루트에서 go build -gcflags -help를 실행하여 확인할 수 있습니다.
go build -a: force rebuilding of packages that are already up-to-date.
디버그 정보 제거
-ldflags="-w -s" 플래그를 추가합니다.
-w: disable DWARF generation-s: disable symbol table
$ go build -a -ldflags="-w -s"; stat -c %s helloworld
1437696바이너리 파일 크기: 1437696 (원본 대비 약 71%)
Function Inlining 비활성화
-gcflags=all=-l 플래그를 추가합니다.
예제 코드에서는 별 효과가 없지만, 대형 프로젝트에서는 최대 10% 정도의 용량 절감을 기대할 수 있습니다.
-l: disable inlining
$ go build -a -ldflags="-w -s" -gcflags=all=-l; stat -c %s helloworld
1437696바이너리 파일 크기: 1437696 (원본 대비 약 71%)
Bound Check 비활성화
-gcflags=all=-B 플래그를 추가합니다.
-B: disable bounds checking
$ go build -a -gcflags=all="-l -B" -ldflags="-w -s"; stat -c %s helloworld
1404928바이너리 파일 크기: 1404928 (원본 대비 약 70%)
기타 gcflags 사용
-gcflags=all=-C 플래그를 추가합니다.
-C: disable printing of columns in error messages
$ go build -a -gcflags=all="-l -B -C" -ldflags="-w -s"UPX 압축
UPX를 이용해 바이너리 파일을 압축할 수 있습니다.
하지만 다음과 같은 단점이 있습니다.
- 프로그램의 초기화 시간 증가
프로그램의 압축이 해제된 후 RAM에 적재되기에, 프로그램이 실행되는 데 걸리는 시간이 증가합니다. - RAM 사용량 증가
선택적으로 적재할 수 있는 부분까지 모두 일괄적으로 RAM에 적재하여, 사용하는 RAM의 양이 증가합니다. - 이미 압축된 바이너리 파일의 경우, 압축 효율 거의 없음
Compression tuning options:
--lzma try LZMA [slower but tighter than NRV]
--brute try all available compression methods & filters [slow]
--ultra-brute try even more compression variants [very slow]$ upx --ultra-brute helloworld32비트로 컴파일
64비트 바이너리가 아닌 32비트 바이너로 컴파일하여 바이너리 파일의 크기를 줄일 수 있습니다.
하지만 32비트 주소 공간, 정수, 시스템 콜 사용 등으로 인해 64비트 바이너리에 비해 성능 저하가 발생할 수 있습니다.
$ GOARCH=386 go build -a -gcflags=all="-l -B -C" -ldflags="-w -s"reflect.Call 미사용
DCE(Dead Code Elimination)은 reflect.Call과 같은 리플렉션이 사용될 시 제대로 작동하지 않습니다.
리플렉션을 사용하지 않으면 훨씬 더 작은 크기의 바이너리 파일을 얻을 수 있습니다.
위험한 방법
다음은 프로그램의 정상 작동을 방해하거나 오류를 일으킬 가능성이 있는 방법입니다.
본인이 무엇을 하고 있는 지 알고 있는 게 아니라면 절대로 따라하지 마세요.
Write Barrier 비활성화
경고
관련 Issue에 따르면 Write Barrier를 비활성화할 시 GC가 제대로 작동하지 않는다고 합니다.
GC 오작동으로 인해 프로그램 실행 시
GOGC=off환경 변수를 추가해야 합니다.
-gcflags=all=-wb=false 플래그를 추가합니다.
-wb: enable write barrier (default true)
$ go build -a -gcflags=all="-l -B -wb=false" -ldflags="-w -s"; stat -c %s helloworld
1380352바이너리 파일 크기: 1380352 (원본 대비 약 69%)
![[Debian] 마인크래프트 서버 설치기 (2) - 마인크래프트 서버](/d/server/debian-minecraft-server-2/logo.86ca6ab6e86a276b4ae79d7fa1bea66f.webp)
![[Debian] 마인크래프트 서버 설치기 (1) - 데비안 설치](/d/server/debian-minecraft-server-1/logo.86ca6ab6e86a276b4ae79d7fa1bea66f.webp)
![[Windows] UAC 확인창 없이 관리자 권한으로 프로그램 실행하기](/d/desktop/skip-uac-prompt/logo.b3b0aec18985fff34c5295de475fdff7.webp)
![[Prism Launcher] 설정](/d/game/prism-launcher-configuration/logo.f3d9c39d1f7cfd4c479d6d90c4917eb2.webp)
![[Prism Launcher] 설치](/d/game/prism-launcher-install/logo.f3d9c39d1f7cfd4c479d6d90c4917eb2.webp)
![[Windows] 업그레이드 차단하기](/d/desktop/windows-block-upgrade/logo.1dc0ab65e12a8e9a0bb1ae2f179d7a83.webp)
![[macOS] Finder 도구 막대에 버튼 추가하기](/d/desktop/macos-add-button-to-finder-toolbar/003.0caaabd1cfdef47e683ebf823397f56e.webp)
![[Android] 삼성 스마트폰 카메라 촬영음 없애기](/d/mobile/android-disable-samsung-smartphone-camera-shutter-sound/logo.afa3141f6fef59f61f9ae0ff6a791fc8.webp)
![[Visual Studio] UI 요소 숨기기](/d/development/visual-studio-hide-ui-element/logo.64e4d119ae00189abe69768e00da86a8.webp)
![[Windows] Wi-Fi 프로필 내보내기/불러오기](/d/desktop/windows-wifi-profile-import-export/logo.0d08578a12ef60ebe6ede2982d77af4a.webp)