First of all you need to understand that what you are doing is pretty strange!
The "normal" way to load a texture is to use the content pipeline and the content manager.
If you really have to load a texture from file and not the content system - you should do this only once for each texture. You should use Texture2D.FromFile
in Game.LoadContent
, and call Dispose
in Game.UnloadContent
(normally the content manager would handle calling Dispose for you - but because you're not going through the content manager you have to call Dispose yourself).
The important thing to realise is that you're working with both managed and unmanaged resources here.
The memory being used by managed objects will be handled by the garbage collector - in this case each instance of Texture2D uses a tiny bit of managed memory. 99% of the time you don't need to worry about it - the garbage collector is really good at handling managed memory - that's its job!
What you do need to worry about is the unmanaged resources - in this case the texture memory being used by all these textures you're loading. Eventually the garbage collector will run, see all these unreferenced Texture2D objects and collect them. When it collects them it will finalize them which, like calling Dispose, will release the unmanaged resources.
But the garbage collector cannot "see" all the unmanaged resources these Texture2D objects are using. It doesn't know when those objects need to be released - you can do a much better job yourself. All you have to do is call Dispose
on your textures when they are no longer needed.
It's because the garbage collector doesn't know about that 30MB of extra memory used by your textures, that it is being accumulated when you are not calling Dispose. In addition to that, what you cannot see when you look at the process memory usage, is all the memory on the GPU that those textures are using!
(The underlying implementation of Texture2D is that it holds a reference to a DirectX texture object - which itself is an unmanaged object using unmanaged main memory - which in turn handles the texture and its associated memory on the GPU. The managed part of a Texture2D object is only about 100-200 bytes - which stores the aforementioned reference and a cache of the texture's width, height, format and so on.)
Now - as for what you are trying to achieve. If you really have a need to load a texture every frame (this is highly unusual), and you then also no longer need the previous texture...
Well, first of all, calling Dispose
on the unused texture each frame is a valid method. You will be depending on the garbage collector to clean up all the garbage this creates (the managed side of Texture2D objects) - this is fine on Windows but might kill your performance on Xbox. At least you won't be leaking unmanaged resources.
A better method, particularly if the texture is the same size each time, is to just keep using the same texture object. Then call Texture2D.SetData
on it with the new texture data each frame.
(If your textures are different sizes, or you have more than one in use at a given time, you might need to implement something like a texture pool.)
Of course, LoadFile takes an actual file, SetData takes raw data. You'll have to implement the data conversion yourself. A good starting point might be this thread on the XNA forum.