Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[bug] Application is slowly leaking memory/taking to much time to garbage collect #639

Open
leragequit opened this issue Jan 12, 2023 · 2 comments
Labels
bug Something isn't working

Comments

@leragequit
Copy link

leragequit commented Jan 12, 2023

What happend?

I have an application which visualizes 4 matrices ,which get updated a lot, around 50 times a second.

When I observer the application in the task manager, sometimes it runs with 200mb of memory continuously, but on other occasions, it will just eat all the 64 GB of RAM that I have, making the system quite unresponsive.

When I profile the application, all of them RAM usage is invisible to me, so I am suspecting that its some internal imgui handling with the textures that do not get freed, or don't get freed fast enough.

I have attached a code sample. It sometimes works for me. You can see it mostly sitting around 100MB, but it sometimes goes up to 500MB.

Again, in the real application I render much more data, so the issue occurs more often.

I tried to find a way to manually "release" the image, but this functionality is not exposed.

Any ideas or mitigations would be greatly appreciated.

Best Regards

Code example

main.go
package main

import (
	"crypto/rand"
	"image"
	"image/color"

	"github.com/AllenDang/giu"
)

var texture *giu.Texture

func loop() {
	giu.Window("window 1").Layout(
		giu.Image(texture).Size(512, 512),
	)
}

func RenderImage(img *image.RGBA) {
	buf := make([]byte, 3)
	for x := 0; x < 256; x++ {
		for y := 0; y < 256; y++ {
			rand.Read(buf)
			img.Set(x, y^255, color.NRGBA{
				R: uint8(buf[0]), G: uint8(buf[1]),
				B: uint8(buf[2]), A: 255,
			})
		}
	}
}

func main() {
	wnd := giu.NewMasterWindow("windows [DEMO]", 640, 480, 0)
	go func() {
		img := image.NewRGBA(image.Rect(0, 0, 256, 256))
		for {
			RenderImage(img)
			giu.NewTextureFromRgba(img, func(tex *giu.Texture) {
				/* we have to find a way to release the texture here */
				texture = tex /* do we leak here ?*/
			})
			giu.Update()
		}
	}()
	wnd.Run(loop)
}

To Reproduce

  1. Run my demo
  2. See memory usage spike sometimes
  3. If the spike rises fast enough, the system will start swapping and memory usage just starts to climb without going down until I kill the application

Version

v0.6.2

OS

Windows 10

@leragequit leragequit added the bug Something isn't working label Jan 12, 2023
@AllenDang
Copy link
Owner

It seems the Finalizer doesn't guarantee to work. You could create a texture from image and release it manually to see whether the problem is solved.

texId, err :=   giu.Context.GetRenderer().LoadImage(...)
giu.Context.GetRenderer().ReleaseImage(...)

@leragequit
Copy link
Author

leragequit commented Jan 16, 2023

Thanks for the quick reply.

I am uncertain if I am holding it wrong but the following code

Code example

main.go
package main

import (
	"crypto/rand"
	"image"
	"image/color"
	"log"

	"github.com/AllenDang/giu"
	"github.com/AllenDang/imgui-go"
)

var texture *giu.Texture
var textureId imgui.TextureID

func loop() {
	giu.Window("window 1").Layout(
		giu.Image(texture).Size(512, 512),
	)
}

func RenderImage(img *image.RGBA) {
	buf := make([]byte, 3)
	for x := 0; x < 256; x++ {
		for y := 0; y < 256; y++ {
			rand.Read(buf)
			img.Set(x, y^255, color.NRGBA{
				R: uint8(buf[0]), G: uint8(buf[1]),
				B: uint8(buf[2]), A: 255,
			})
		}
	}
}

func main() {
	wnd := giu.NewMasterWindow("windows [DEMO]", 640, 480, 0)
	go func() {
		img := image.NewRGBA(image.Rect(0, 0, 256, 256))
		for {
			RenderImage(img)
			// textureId, err := giu.Context.GetRenderer().LoadImage(img)
			_, err := giu.Context.GetRenderer().LoadImage(img)
			if err != nil {
				log.Fatalf("loadImage failed: %v", err)
			}
			// texture = giu.ToTexture(textureId)
			giu.Update()
		}
	}()
	wnd.Run(loop)
}

leads to a

Exception 0xc0000005 0x0 0x1408 0x7ffba4c4dcd9
PC=0x7ffba4c4dcd9
signal arrived during external code execution

on line

_, err := giu.Context.GetRenderer().LoadImage(img)

and when stepping down into the function it appear that

gl.GenerateMipmap(gl.TEXTURE_2D)

is the line crashing

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

2 participants