Archived

This topic is now archived and is closed to further replies.

tresspassor

Free Texture from Memory

Recommended Posts

Evening, I have a simple application that does the following: Press F1 Key: Load a number of TGA textures based on NeHe's tutorials Press F2 Key: Unload all TGAs and load different TGAs After I load a texture I call free(imageData). When I am loading the new textures, I unload the old textures by calling: glDeleteTextures. But, when I do this and have Task Manager on (windows 2000), it doesn't appear that the memory is actually getting free'd. When I hit the F2 key the memory goes up a notch. If I hit it again, it goes up again. Is this supposed to happen? Or should the memory stay the same? [edited by - tresspassor on October 6, 2003 4:13:27 PM]

Share this post


Link to post
Share on other sites
With glDeleteTextures you delete the texture form the memory of the videocard! And the taskmanager only shows the memorystate of the computer Ram!

So it should be ok. Because after you send the texture to opengl you delete the copy in the Ram.

Share this post


Link to post
Share on other sites
You''re leaking memory. glDeleteTexture releases the current texture object''s image memory; it doesn''t delete the object itself. By calling glGenTexture repeatedly, you create more and more texture objects.

Only call glGenTexture once. Initialize a GLuint variable to zero, and use this to hold the texture index returned from glGenTexture. When loading a new texture, call glDeleteTexture to free the image memory, then re-use the current texture object (by calling glTexImage2D, for instance, with the old texture index), instead of calling glGenTexture again.

Share this post


Link to post
Share on other sites
Ferdinand the Bull: are you sure about that?

glGenTextures
glGenTextures returns n texture names in textures. There is no guarantee that the names form a contiguous set of integers; however, it is guaranteed that none of the returned names was in use immediately before the call to glGenTextures.

The generated textures have no dimensionality; they assume the dimensionality of the texture target to which they are first bound (see glBindTexture).

Texture names returned by a call to glGenTextures are not returned by subsequent calls, unless they are first deleted with glDeleteTextures.

glDeleteTextures
glDeleteTextures deletes n textures named by the elements of the array textures. After a texture is deleted, it has no contents or dimensionality, and its name is free for reuse (for example by glGenTextures) . If a texture that is currently bound is deleted, the binding reverts to 0 (the default texture).


From my reading of that glDeleteTextures should completely delete the entire texture object and therefore continuous use of glGenTextures/glDeleteTextures should not cause a memory leak.

Enigma

Share this post


Link to post
Share on other sites
Yes, I''m sure. Try it and see. I''m familiar with the documentation. I can''t tell you if it''s Window''s implementation that''s wrong, or the docs, but repeated use as the docs describe does result in a leak, exactly as trespassor describes, and it does work, just as I''ve described. I think the docs are poorly worded here. The memory usage as seen with the Win2K performance monitor is real - repeated use of glGenTexture causes a leak.

Share this post


Link to post
Share on other sites
Ferdinand : You have a point for the fact if you manage textures manually (create a single texture array and reuse it instead of calling glDeleteTextures+glGenTextures) then you're 100% sure that texture memory is freed. With that said, it's wrong to tell that glGenTextures will always allocate new texture names. Because, as stated by the specification, if glDeleteTextures is called, then the namespace sent to glDeleteTextures goes "available" and can be returned by glGenTextures once again. With that said, implementations are free to return every valid name from glGenTextures, not necessariy names that were freed by glDeleteTextures.
Anyway in the case that calling glDeleteTextures doesn't free memory, I'd rather say that such drivers are leaked. Which graphics card and which driver do you use tresspassor ?

[edited by - vincoof on October 7, 2003 2:46:56 PM]

Share this post


Link to post
Share on other sites
I've had a simmilar "problem" like you , I was creating number of GL textures and then deleting them. There was no memory leak in my program, but task manager showed increased amount of memory in use for my program. I've always tested for small amounts of textures loaded (10) then once just for fun i tried loading&deleting about 5000 of them. I always keep about 20 of them in VRAM and just delete one and create a new one. And to my suprise something nice happend. The memory usage just repeated going up and down a bit (not in sync with loading). So I figured the OS (win2k) or drivers didn't "freed" memory the moment I requested but only once in a while.
So, try creating a function that loads a texture and deletes it after that. And call this in a loop a few 100 times. While program is running watch proceses memory usage in task manager and see what happens.

ps : sorry for the typos

You should never let your fears become the boundaries of your dreams.

[edited by - _DarkWIng_ on October 7, 2003 2:58:51 PM]

Share this post


Link to post
Share on other sites
Darkwing - what you saw was the Windows memory manager in action. I believe the phenomenon I describe is not that you describe - in the situation I describe, it doesn''t release the memory until the program is halted. The amount of memory used continues to climb until the app exits.

Vincoof - I''m not saying glGenTextures won''t re-use the name made available by glDeleteTexture, I''m saying that glDeleteTex doesn''t release all the resources (memory) used by the texture object, and subsequent calls to glGenTex will consume additional memory. This is independent of video memory and video drivers, but involves system memory, where it is seen by the performance monitor.

As I said, try it yourself and watch what happens. The phenomenon will occur as I describe, independent of video board and driver. ( Try this, as well - render to an off-screen DIBSection instead of to the screen. This will use only the software implementation, rather than the hardware implementation on your machine.) You''ll see the same thing happen here - memory usage will inexorably climb every time glGenTexture is called, and it won''t be released until the program is halted.

Actually, re-reading the docs, I don''t think that what I''m saying contradicts them. The texture object is in the same state after a call to glDeleteTex as it was immediately after having called glGenTex - ''no dimensionality'' and all. What I''m saying is that that name can be re-used in a call to glTexImage or whatever and re-bound. Creating a new texture name will result in a memory leak (which won''t be cleaned up by the OS''s memory manager), and is unnecessary.

Try it - I''d be interested in hearing what you find. I''ll gladly concede the point if proven wrong.

Share this post


Link to post
Share on other sites
In the case that names are re-used after calling glDeleteTextures + glGenTextures then it's more than obvious that old memory should be freed. I agree that it does not contradict the specification, as the spec is very flexible WRT memory management, but still it's a memory leak situation.

As for allocating endless data, not necessarily GL, and see the memory grow forever : it may be just cached. In that case, the system will handle it until he doesn't need it anymore, and then it should join what DarkWing said : the system will free the useless memory himself when other applications allocate memory.

[edited by - vincoof on October 7, 2003 10:39:58 PM]

Share this post


Link to post
Share on other sites
Update:

Soon as I moved glGenTextures to only be called once I no longer had the memory notch problem. Now it will raise up a little, then drop back down to normal. Very cool.

Thanks for all of your help.

vincoof -> Asus V7700 64M


[edited by - tresspassor on October 7, 2003 10:47:22 PM]

Share this post


Link to post
Share on other sites
Asus V7700 64M -> that''s the GeForce2 GTS that integrates stereo viewing on-board, is it ?

Do you use the latest nvidia drivers ? Or do you use custom drivers (typically drivers that support stereo viewing) ?

As for memory checking, what kind of memory do you check ? Under Windows 2000 there are at least two fields related to memory for each process.

Share this post


Link to post
Share on other sites
Do you use the latest nvidia drivers ? Or do you use custom drivers (typically drivers that support stereo viewing) ?
---------------
NVidia 6.14.10.4403


As for memory checking, what kind of memory do you check ? Under Windows 2000 there are at least two fields related to memory for each process
---------------
I was checking the overall mem usage, I first noticed it just watching the performance monitor tab. I''ll watch the other memory fields and get more details.


that''s the GeForce2 GTS that integrates stereo viewing on-board, is it ?
---------------
It came with 3d glasses that plugged into the back of the card and made me feel like I had my head pressed against a strobe light.

Share this post


Link to post
Share on other sites
quote:
Original post by tresspassor
that''s the GeForce2 GTS that integrates stereo viewing on-board, is it ?
---------------
It came with 3d glasses that plugged into the back of the card and made me feel like I had my head pressed against a strobe light.


If you activate stereo viewing in the drivers (I don''t know how good nvidia drivers are in this regard though) then you can switch to stereo without changing a single line of code in your program. In fact, all you need is to swap to fullscreen mode and stereo starts immediately. With that said, you need a monitor that supports 120Hz refresh rates at least.

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
anyone ever use the disclaim() function? I can''t seem to find it anywhere.. or is that only a linux function?

I''m worried that my malloced memory isn''t being freed all the way when I call free()

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
http://www.faqchest.com/linux/KERNEL/kern-97/kern-9705/kern-970519/kern97051411_17141.html
"It is not sufficient to free the space that was malloced or calloced. free releases only the address range that the structure occupied. In order to release the real memory and paging space, you must disclaim the space as well."

So is there a way to (really) free the memory in windows?

Share this post


Link to post
Share on other sites