diff --git a/madvdontneed.go b/madvdontneed.go new file mode 100644 index 0000000..233fadb --- /dev/null +++ b/madvdontneed.go @@ -0,0 +1,47 @@ +// +build linux + +package main + +import ( + "log" + "os" + "runtime/debug" + "strings" + "syscall" + "time" +) + +// Inject madvdontneed=1 as soon as possible. + +var _ = func() struct{} { + // If GODEBUG is not empty, then use that instead of trying to exec our own. + if os.Getenv("GODEBUG") != "" { + return struct{}{} + } + + // Do magic. + var environ = append(os.Environ(), "GODEBUG=madvdontneed=1") + + log.Println("execve(2)ing with madvdontneed=1 for aggressive GC.") + + if err := syscall.Exec(os.Args[0], os.Args, environ); err != nil { + log.Fatalln("Fatal error while executing:", err) + } else { + os.Exit(0) + } + + return struct{}{} +}() + +func init() { + // Aggressive memory freeing you asked, so aggressive memory freeing we will + // deliver. + if strings.Contains(os.Getenv("GODEBUG"), "madvdontneed=1") { + go func() { + log.Println("Now attempting to free memory every 5s... (madvdontneed=1)") + for range time.Tick(5 * time.Second) { + debug.FreeOSMemory() + } + }() + } +} diff --git a/main.go b/main.go index bdb2341..f5edb4c 100644 --- a/main.go +++ b/main.go @@ -1,11 +1,6 @@ package main import ( - "os" - "runtime/debug" - "strings" - "time" - "github.com/diamondburned/cchat-gtk/internal/gts" "github.com/diamondburned/cchat-gtk/internal/log" "github.com/diamondburned/cchat-gtk/internal/ui" @@ -19,19 +14,6 @@ import ( // destructor is used for debugging and profiling. var destructor = func() {} -func init() { - // Aggressive memory freeing you asked, so aggressive memory freeing we will - // deliver. - if strings.Contains(os.Getenv("GODEBUG"), "madvdontneed=1") { - go func() { - log.Println("Now attempting to free memory every 5s... (madvdontneed=1)") - for range time.Tick(5 * time.Second) { - debug.FreeOSMemory() - } - }() - } -} - func main() { gts.Main(func() gts.MainApplication { var app = ui.NewApplication()