Tracking memory usage throughout your game

As my Lua game got more complex, I noticed that the game was slowing down over tme. My hunch was that this was a memory “leak”. So I decided to track memory usage to see if my code was behaving itself…

It wasn’t. I was losing 32KB of memory every level load and this turned out to be of my own making.

Simulator

Use Simulator > Window > Lua Memory

pros

  • sortable
  • displays everything

cons

  • game paused while displayed
  • does not update live

Also be wary that memory allocations are different on Simulator and Device.

Device & Simulator

There’s a Lua command called collectgarbage("count") that when called with the count parameter reports memory, which is ideal to print as debug logging.

I used a call to remember the inital memory usage, and then additional calls to it at the end of each of my methods as below

Note: you may have to drill in to more places to lock on to where exactly your memory being allocated and never freed.

There may be better ways to do this, but this was enough for me.

I hope this is a useful guide to others.

pros

  • displays whilst game runs
  • updates live

cons

  • not sortable
  • displays specifics
function game:init()
	...

	if debug == true then
		self.memoryInit = collectgarbage("count")*1024
		self.memoryUsed = self.memoryInit

		print( string.format("initial memory usage (%d bytes)", self.memoryInit) )
	end
end
function game:levelLoad()
	...

	if debug == true then
		self:memoryCheck()
	end
end
function game:memoryCheck()
	local new <const> = collectgarbage("count")*1024
	local diff <const> = new - self.memoryUsed
	
	-- still making large numbers of allocations
	if diff > self.memoryInit then
		self.memoryUsed = new
		return
	end
	
	-- fine grained memory changes
	if diff > 0 then
		print(string.format("memory use\t+%dKB (%d bytes)", diff//1024, new - self.memoryInit))
	elseif diff < 0 then
		print(string.format("memory free\t%dKB (%d bytes)", diff//1024, new - self.memoryInit))
	end

	self.memoryUsed = new
end
7 Likes

How were you managing to leak memory in a garbage collected language?

1 Like

@rob I’ll write a more detailed reply tomorrow, but certain SDK functions currently do not release all memory correctly. Bugs have been filed! For me it was related to reading/loading JSON.

It took me a bunch of changes to get my memory counter on level 1 to be the same after cycling through all my dozens of levels. Who’d have thought it would be that difficult!?

1 Like

Thanks this code really helps me to track a memory leak I had.

1 Like

This looks great Matt. I love the idea of choosing a moment in time in your game's flow (e.g. starting a level) and comparing memory usage for it over a period of time. Helps eliminate the noise of expected memory usage consumption during play. Definitely giving this a go.

1 Like