Rendertarget memoryleak / misuses?

I am currently making a mapeditor for my game. The background is made up of 2 large Texture2D that I generate using a RenderTarget2D. This works very well when I only need to generate the textures once, however if this is done a lot (Which happens when mapediting) it starts using more and more memory. The memory is never freed again even though I am calling .Dispose(), I am at a bit of a loss. So it got me wondering if I am misusing the Rendertarget and if there is an alternative to what I am doing.

Code
More Code

Edit: I’ll add that not using .Dispose() increases the memory usage a lot

How are you certain the rendertarget part is taking up more memory? wouldn’t you expect a level to take up more and more memory as variation grows?

It only happens whenever the .DrawingToTexture() is called, regardless of whether a change has happened or not.

A gif showing the increased use of memory
The method call only happens once whenever the mouse enters a different tile, so it is not because it is running every update call.

Edit: I might not have ensured that it is only called once… Might be this, currently testing

Edit2: I wasn’t limiting it, limiting it decreased the time it takes, but still slowly creeping up.

I would say it comes from the fact that you create, each time you call DrawingToTexture():

  • a new RenderTarger
  • a new spritebatch
    And this is done twice when you call RefreshTexture().

You should create the RTs and the spritebatch when loading the app, this should resolve the problem, and as a bonus, should go faster.

I use 9 RTs in my engine and no problem with the memory allocation.

As a bonus, can you tell us why his approach causes a memory inflation…? I would have thought the spritebatch and rendertarget would just be destroyed when their containing method is done executing? i.o.words: What accounts for the ever increasing ram usage?

It’s the GarbageCollector which should free the objects, they are not freed as soon as you exit the method. (or you should use something like this:

using(SpriteBatch sb = new SpriteBatch(gfxdev))
{

}

to ensure it is.
As it is called when mouse hovering a different tile, and RTs are allocated twice each mouse move, maybe the creation is faster than the garbage collector can detect the generations that need to be freed.
As I have written, “I would say”, I’m not saying i’m an expert, but for sure creating variables each frames is really bad. Moreover when it comes to RenderTargets, which use a lot more memory than just an array depending on the resolution choosen.
A profiling of the app should point to the culprit.

2 Likes

Thank you Alkher and monopalle, it was the Spritebatch, adding SpriteBatch.Dispose() to the end of the DrawingToTexture fixed it!
A single Spritebatch works as well.

I tried making a single RT, but the Texture2D is tied to the RT so that approach will only allow me to make a single texture, unless I copy it, which is very resource intensive.

Glad to help :slightly_smiling:

using(SpriteBatch sb = new SpriteBatch(gfxdev))
{

}

calls Dispose() implicitly :wink:

2 Likes