Can't free texture memory when sprites have physics

This had me stumped for a while, as I thought one of my modules was leaking memory. Maybe I’m omitting something, but the docs all seem to say that DisplayObjects with RigidBodies attached are disposed of by the usual removeSelf(), or spriteSheet:dispose(). But this doesn’t seem to work when a physics body is attached to a sprite. Regular DisplayObjects with physics bodies behave as expected. Here’s a minimalist example:

require "sprite"  
require "out"  
require "physics"  
  
physics.start()  
  
local prevTime = system.getTimer()  
local ix = 1  
  
local data, spriteSheet, spriteSet  
local instances = {}  
local onFrame  
local startup  
  
local tm = function() print("Texture memory used: " .. system.getInfo("textureMemoryUsed")) end   
  
local f1 = function()  
 data = out.getSpriteSheetData()  
 spriteSheet = sprite.newSpriteSheetFromData("out.png", data)  
 spriteSet = sprite.newSpriteSet(spriteSheet, 1, 64)   
  
 tm()  
end  
  
local f2 = function()  
 for i = 1, 10 do  
 local instance = sprite.newSprite(spriteSet)  
 physics.addBody(instance, { density = 1.0, friction = 0.3, bounce = 0.2, radius = 50} )  
 instances[i] = instance  
 end  
end  
  
local f3 = function()  
  
 -- this doesn't free memory if physics body is attached  
 for i = 1, #instances do  
 instances[i]:removeSelf()  
 end  
  
 -- neither does this  
 spriteSheet:dispose()  
end  
  
local f4 = function()  
 Runtime:removeEventListener("enterFrame", onFrame)  
  
 tm()  
end  
  
local tab = { f1, f2, f3, f4 }  
  
onFrame = function(event)  
 if event.time - prevTime \>= 2000 then   
 prevTime = event.time  
 tab[ix]()  
 ix = ix + 1  
 end  
end  
  
tm()  
  
startup = function(event)  
 if event.phase == "began" then  
 print("startup: adding onFrame")  
 Runtime:addEventListener("enterFrame", onFrame)  
 ix = 1  
 end  
end  
  
display.getCurrentStage():addEventListener("touch", startup)  
  

If you comment out “physics.addBody” all works fine and the final check shows zero. Otherwise there’s no reduction. In my case:

Texture memory used: 0
startup: adding onFrame
Texture memory used: 2097152
Texture memory used: 2097152

After commenting out addBody call:

Texture memory used: 0
startup: adding onFrame
Texture memory used: 2097152
Texture memory used: 0

If you iterated through a few times you’ll find that no additional memory is allocated. It’s just that the first allocation stays. Not so good if loading multiple sequential levels.

For any new users wondering why the convoluted test routine, texture memory is not freed - or at least up to date reporting of it - doesn’t happen until the next enterFrame event.

I can provide the “out” files from TexturePacker but I don’t know how to do forum message attachments. But it’s pretty easy to test. Or preferably I can be corrected by one of the fine Corona forum identities.
[import]uid: 3953 topic_id: 2665 reply_id: 302665[/import]

So should I assume we can’t have both sprites and physics if we don’t want to leak memory? (Sure, that’s a rhetorical question, sorry.)

Or is there a way to detach a physics body from a sprite or display object? The docs only list a removeSelf() call on the DisplayObject that has an attached physics body. This does not work if the object is a sprite.

Unless I’m doing something stupid, it’s a significant issue because sprite sheets tend to be pretty big. In a larger game it would not be a good thing for unused sprite sheets to be occupying texture memory.

Anything else I have to do to get Ansca’s attention? (I’m not very good at dancing, and you really don’t want to hear my singing.) [import]uid: 3953 topic_id: 2665 reply_id: 7785[/import]

I know memory management is not a very sexy subject, but surely others have come across this issue?

It could get downright unsexy if your commercial Corona app crashes after a few level loads.

I guess that’s a bump in too many words. [import]uid: 3953 topic_id: 2665 reply_id: 7926[/import]

Anybody know the answer? [import]uid: 9936 topic_id: 2665 reply_id: 8018[/import]

MarkHenryC - I suggest going through the Ansca bug tracker, or emailing support@anscamobile.com directly with the issue.

Until then, you can do what I do–don’t use sprites for now, instead, modify movieclip.lua to your needs (I know, it’s not as nice as using sprites, and in many cases not as easy or efficient, but it’s A LOT better than leaking memory!).
[import]uid: 7849 topic_id: 2665 reply_id: 8023[/import]

I’m sure this is a bug. [import]uid: 54 topic_id: 2665 reply_id: 8097[/import]

@ jonbeebe thanks for the feedback. I had already posted it to the “issue” database and sent a couple of emails. Emails didn’t get results and the bug tracker, frankly, is looking a bit forlorn. [import]uid: 3953 topic_id: 2665 reply_id: 8437[/import]

FWIW, we *are* tracking this as internal issue FB#1541. [import]uid: 6787 topic_id: 2665 reply_id: 8679[/import]

That is worth something, snarla. [import]uid: 3953 topic_id: 2665 reply_id: 8681[/import]

@MarkHenryC did you ever found a solution, I’m in front of the same issue and it makes big
problems because we are using a lot of big sprite sheets as physics bodies in our game…???

Greatings Michael from Berlin [import]uid: 12632 topic_id: 2665 reply_id: 28897[/import]

Hello Mark,

This issue has been confirmed fixed in the latest release, build 505 for Windows.

An important detail to note is that a sprite’s image memory is not released until a sprite sheet’s dispose() function has been called. But that said, memory is not immediately released after calling the dispose() function. Instead, it is scheduled to be released by the next render pass; ie: memory is freed by the next frame event. [import]uid: 32256 topic_id: 2665 reply_id: 39659[/import]