Post-processing and memory leak

Hello everyone! I’m try to build a simple post-processing unit for my game and witness a memory leak. So now I’m interested: is it a feature or my code is bad:) I’m using a quite primitive way: I’m making a screenshot, then use some fill effects. I’m trying not to make screen captures each frame using a timer instead. It all works fine, but there is a small but constant memory leak, even if fill effects are turned off. If the timer is simply making screenshots, there is a leak as well. Once I turn off this timer, the game is working fine without any memory leaks, so it looks like screen captures filling the memory, but it is strange because I’m trying to clean them up each cycle.

// An endless timer to make screen captures each 50 ms

    timer.performWithDelay(50,function()

   //Clean previous screenshot
display.remove(Game.UI.ScreenCap)	
Game.UI.ScreenCap=nil	

    //Create a new screenshot	
Game.UI.ScreenCap=display.captureBounds(Screen.Bounds,false)		
Game.UI.ScreenCap.x,Game.UI.ScreenCap.y=Screen.WidthHalf,Screen.HeightHalf

    //Apply some effects here
    Game.UI.ScreenCap.fill.effect =...

  end,0)

display.remove() only flags the object as removable. GC will then remove it when it has some free cycles.

try calling collectgarbage() and see if that helps in your situation?

you can also try removing the filter before removing the object in case a reference is being kept there too.

2 Likes

Thank you! I’ve tried to put collectgarbage(“collect”) after Game.UI.ScreenCap=nil, the leak is still present.

But how to remove the filter? Make object’s field ‘fill’ nil? Something like this Game.UI.ScreenCap.fill=nil?

It is interesting, that the memory leak is noticeable even if filters are turned off. It looks like display.captureBounds provides some data, that is not properly collected by the garbage collector.

What happens if you use display.capture(displayObject) instead? Is the leak still persistent?

This probably won’t show you the desired result, but I think it may solve the memory leak.

2 Likes

Unfortunately display.capture(displayObject) creates a memory leak as well.

Try this

local img
timer.performWithDelay(50, function()
  display.remove(img) 
  img = display.captureScreen(true)   
  print("Tex: "..math.floor(system.getInfo("textureMemoryUsed")/1048576).."mb   Lua:"..math.floor(collectgarbage("count")/1024).."mb")
end, 0)

I get this (no leaks)

23:03:34.933 Tex: 15mb Lua:0mb
23:03:35.298 Tex: 15mb Lua:0mb
23:03:35.627 Tex: 15mb Lua:0mb
23:03:35.971 Tex: 15mb Lua:0mb
23:03:36.315 Tex: 15mb Lua:0mb
23:03:36.645 Tex: 15mb Lua:0mb
23:03:36.989 Tex: 15mb Lua:0mb
23:03:37.334 Tex: 15mb Lua:0mb
23:03:37.662 Tex: 15mb Lua:0mb
23:03:38.007 Tex: 15mb Lua:0mb
23:03:38.335 Tex: 15mb Lua:0mb

4 Likes

Thank you very much for your example. There is indeed no any memory leak, but there is also a trick. You are using display.captureScreen with a true flag. The code is trying to save a screen capture on a disk drive. That is taking some time, look at the log: there are only about 3-4 cycles per second, so the code is slow and Solar 2D has a lot of time to collect the garbage. So it seems that even with collectgarbage(“collect”) in the timer, the system has no time for collecting the garbage in my code. I’ve made some experiments by myself and once I change the delay value, for example, to 360 ms instead of 50 ms, so the memory leak is almost gone… but fps is too low:) It worth to mention that beside a memory monitor inside the Lua code, I’m using the Task manager, monitoring a memory used by my Windows build. If, for instance, I’m using the timer with something like 35 ms, so my Windows build is losing about 200-300 KB of memory in a minute and losing none once the post-processing is turned off. It also interesting that if I replace display.capture with display.newImage, displaying an image of the same size as a screenshot all works great without any big leaks as well. So it seems that display.capture provides more garbage the engine can’t collect properly.

I’d use a Canvas instead :slight_smile:

1 Like