gotk4 icon indicating copy to clipboard operation
gotk4 copied to clipboard

Memory is not freed when destroying Window

Open malaupa opened this issue 2 years ago • 2 comments

First of all: This project is nice work!

But while I'm playing with gotk4, I realized, that memory is not freed after a window or a application is closed/destroyed or finished:

package main

import (
	"log"
	"os"
	"runtime"
	"runtime/debug"
	"time"

	"github.com/diamondburned/gotk4/pkg/gio/v2"
	"github.com/diamondburned/gotk4/pkg/gtk/v4"
)

func main() {
	time.Sleep(time.Second * 5)
	stats := &runtime.MemStats{}
	debug.FreeOSMemory()
	runtime.ReadMemStats(stats)
	log.Printf("%vKB\n", stats.Sys/1024)

	app := gtk.NewApplication("com.github.diamondburned.gotk4-examples.gtk4.simple", gio.ApplicationFlagsNone)
	app.ConnectActivate(func() {
		window1 := gtk.NewApplicationWindow(app)
		window1.SetTitle("gotk4 Example #1")
		window1.SetChild(gtk.NewLabel("Hello from Go!"))
		window1.SetDefaultSize(400, 300)
		window1.Show()
		window2 := gtk.NewApplicationWindow(app)
		window2.SetTitle("gotk4 Example #2")
		window2.SetChild(gtk.NewLabel("Hello from Go!"))
		window2.SetDefaultSize(400, 300)
		window2.Show()
		window3 := gtk.NewApplicationWindow(app)
		window3.SetTitle("gotk4 Example #3")
		window3.SetChild(gtk.NewLabel("Hello from Go!"))
		window3.SetDefaultSize(400, 300)
		window3.Show()
		go func() {
			stats := &runtime.MemStats{}
			debug.FreeOSMemory()
			runtime.ReadMemStats(stats)
			log.Printf("%vKB\n", stats.Sys/1024)

			time.Sleep(time.Second * 5)
			window1.Close()
			window1.Destroy()
			stats = &runtime.MemStats{}
			debug.FreeOSMemory()
			runtime.ReadMemStats(stats)
			log.Printf("%vKB\n", stats.Sys/1024)

			time.Sleep(time.Second * 5)
			window2.Close()
			window2.Destroy()
			stats = &runtime.MemStats{}
			debug.FreeOSMemory()
			runtime.ReadMemStats(stats)
			log.Printf("%vKB\n", stats.Sys/1024)

			time.Sleep(time.Second * 5)
			window3.Close()
			window3.Destroy()
			stats = &runtime.MemStats{}
			debug.FreeOSMemory()
			runtime.ReadMemStats(stats)
			log.Printf("%vKB\n", stats.Sys/1024)
		}()
	})

	if code := app.Run(os.Args); code > 0 {
		os.Exit(code)
	}

	stats = &runtime.MemStats{}
	debug.FreeOSMemory()
	runtime.ReadMemStats(stats)
	log.Printf("%vKB\n", stats.Sys/1024)
}

This prints:

2023/04/14 19:47:22 13373KB
2023/04/14 19:47:22 13437KB
2023/04/14 19:47:27 13693KB
2023/04/14 19:47:32 13693KB
2023/04/14 19:47:37 13693KB
2023/04/14 19:47:37 13693KB

Any suggestion what I'm doing wrong?

malaupa avatar Apr 14 '23 17:04 malaupa

I'm not too sure myself, but the windows might only be freed after several GC cycles. It might be better to run the GC every second or so in a background goroutine and monitor memory usage that way.

diamondburned avatar Apr 15 '23 22:04 diamondburned