Welcome, Guest. Please login or register. Did you miss your activation email?

Author Topic: Memory leak with Sf::RenderTexture, help! [Solved]  (Read 4389 times)

0 Members and 1 Guest are viewing this topic.

killerloader

  • Newbie
  • *
  • Posts: 28
    • View Profile
Memory leak with Sf::RenderTexture, help! [Solved]
« on: January 12, 2015, 03:04:36 pm »
I'm relatively new to trying to preserve memory by eliminating memory leaks.
Anyways, i was watching the memory of my program and i realized that the memory used by my RenderTextures was not getting released or cleared, so every time the map changed, more and more memory was being used up.
I've recreated my situation in this while loop statement below, as it would be too hard to write out my entire code, however using this code produces the same memory leak.

       
std::vector <sf::RenderTexture*> overlaySurfaces;
int mapWidth=2000;
int gridOverlaySquared=256;
int mapHeight=2000;
while(true){
    int Xmax_=ceil((double)mapWidth/(double)gridOverlaySquared);
    int Ymax_=ceil((double)mapHeight/(double)gridOverlaySquared);
    overlaySurfaces=vector<sf::RenderTexture*> (Xmax_*Ymax_);
    for(int i=0; i<overlaySurfaces.size(); i++)
    {
    overlaySurfaces[i]=new sf::RenderTexture;
    overlaySurfaces[i]->create(gridOverlaySquared,gridOverlaySquared);
    }
    for(int i=0; i<overlaySurfaces.size(); i++)
        delete overlaySurfaces[i];
    overlaySurfaces.clear();
    }

As i said, i'm pretty new to this, so how am i meant to properly delete the RenderTexture when they are in a pointer vector.

This code quickly uses a lot of RAM.

P.S. Now obviously this code is completely inefficient, trust me, my game is not this bad haha, even with the memory leak it would not use much ram probably. But i want to learn how to fix it, or if i can't fix it, then i can easily work around it.
« Last Edit: January 13, 2015, 10:58:30 am by killerloader »

eXpl0it3r

  • SFML Team
  • Hero Member
  • *****
  • Posts: 10846
    • View Profile
    • development blog
    • Email
Re: Memory leak with Sf::RenderTexture, help!
« Reply #1 on: January 12, 2015, 03:15:08 pm »
With modern C++ (that is C++11) you shouldn't have to manually manage memory and should instead make use of RAII, which can be easily applied to resources with smart pointers (see this article).

So you talk about "watching memory usage" and "memory leaks", question is, how did you watch it? And how do you know it's actually a memory leak?

Without a complete and minimal example, we can't really tell what could cause issues, because for all we know, you might have removed the bad code without knowing it. ;)
Official FAQ: https://www.sfml-dev.org/faq.php
Official Discord Server: https://discord.gg/nr4X7Fh
——————————————————————
Dev Blog: https://duerrenberger.dev/blog/

killerloader

  • Newbie
  • *
  • Posts: 28
    • View Profile
Re: Memory leak with Sf::RenderTexture, help!
« Reply #2 on: January 12, 2015, 03:19:20 pm »
Watching with task manager, and I'm testing this exact code that i posted here (After i just edited a few mistakes a few seconds ago) and it's raising my RAM usage upto 1gb (From 100mb~) in 1 minute.
Thanks i'll read the article!
« Last Edit: January 12, 2015, 03:24:18 pm by killerloader »

Jesper Juhl

  • Hero Member
  • *****
  • Posts: 1405
    • View Profile
    • Email
Re: Memory leak with Sf::RenderTexture, help!
« Reply #3 on: January 12, 2015, 06:06:08 pm »
My 2 cents:

As eXpl0it3r already mentioned, use RAII and smart pointers. Don't call new/delete yourself (you almost never need to), instead use std::make_unique and std::make_shared when you need to allocate on the heap. If you are not using C++14 but are stuck with C++11 then you will unfortunately be lacking std::make_unique, but you can easily implement it yourself (basically you can just copy the template directly from the text of the standard; just don't put it in namespace std). If you don't want to do that, then at least make calls to new go directly into the smart pointer in a statement that does nothing else
auto ptr = std::unique_ptr<someType>(new someType);
. Don't do stuff like creating the smart pointer as part of a function call etc, since this may leak if the compiler evaluates function call arguments in an unfortunate order (new called first, other funtion evaluated that throws, then assigning of new result to smart pointer ctor) - the std::make_... functions avoid this problem.

Prefer allocating objects on the stack rather than on the heap. Stack allocated objects are automatically destroyed when you leave the scope they are defined in, regardless of how you leave that scope. Stack variable are also often more CPU cache friendly.

Define variables in as narrow a scope as their lifetime needs dictate and no wider.

Use tools such as Valgrind, clang-analyze and the Google/LLVM/GNU sanitizers to help you find mem leak issues in your current code.

Don't use global variables. Their lifetime is the lifetime of the program and they will take up memory for the entire duration of the program (although that's really the least of their problems).
« Last Edit: January 13, 2015, 05:50:35 pm by Jesper Juhl »

killerloader

  • Newbie
  • *
  • Posts: 28
    • View Profile
Re: Memory leak with Sf::RenderTexture, help!
« Reply #4 on: January 13, 2015, 04:20:50 am »
Thankyou Jesper, i will look into using those tools, and upgrading to c++14 if i haven't already got it.
You can create your own scope without the need of a statement beforehand, so basically just a random set of curly braces yeah? never actually tried it before.

I just realized that calling delete in my code above actually uses more RAM than if i didn't call it....

I'd like to allocate this on the stack, but unfortunately it is non-copyable so it does not work well with this vector.

I suppose this question is sort of answered, but for the hell of it, why would the render texture not get deleted when calling delete on it?

eXpl0it3r

  • SFML Team
  • Hero Member
  • *****
  • Posts: 10846
    • View Profile
    • development blog
    • Email
Re: Memory leak with Sf::RenderTexture, help!
« Reply #5 on: January 13, 2015, 10:14:23 am »
It has most likely to do with the infamous context leak or a leak in the GPU driver.
You could try the feature/gl_dev_new branch.
Official FAQ: https://www.sfml-dev.org/faq.php
Official Discord Server: https://discord.gg/nr4X7Fh
——————————————————————
Dev Blog: https://duerrenberger.dev/blog/

binary1248

  • SFML Team
  • Hero Member
  • *****
  • Posts: 1405
  • I am awesome.
    • View Profile
    • The server that really shouldn't be running
Re: Memory leak with Sf::RenderTexture, help!
« Reply #6 on: January 13, 2015, 10:57:00 am »
As eXpl0it3r said, this partially has to do with the fact that a tonne of contexts are created by SFML, and they... "leak". Strictly speaking they don't really leak, since they get culled right before the application terminates, but it is something people should be aware of. Don't create too many RenderTextures if there are alternatives.

Oh... and I don't think feature/gl_dev_new fixes this :P.
SFGUI # SFNUL # GLS # Wyrm <- Why do I waste my time on such a useless project? Because I am awesome (first meaning).

killerloader

  • Newbie
  • *
  • Posts: 28
    • View Profile
Re: Memory leak with Sf::RenderTexture, help! [Solved]
« Reply #7 on: January 13, 2015, 11:03:49 am »
Thankyou for all your help guys.
I think i have to use RenderTextures, i'm using them on a grid, so a single map could have over 40 or so, i just use them so i can draw infinite blood and other things to the surface of the map without it disappearing.
The RenderTextures only get created at the first time something tries to get drawn to its grid cell.
Because of this memory leak, i've just made it so they never get destroyed, but rather, when the game loads a new map, it just clears the ones that are being used so that it doesn't have to create it again.
Overall, an entire map would not use more than 200mb of ram, so it wont make the game use too much RAM (Still not a very good way of doing it but it's to the best of my knowledge)

eXpl0it3r

  • SFML Team
  • Hero Member
  • *****
  • Posts: 10846
    • View Profile
    • development blog
    • Email
Re: Memory leak with Sf::RenderTexture, help!
« Reply #8 on: January 13, 2015, 11:07:03 am »
Oh... and I don't think feature/gl_dev_new fixes this :P.
Ah okay, my mistake then. ;)

I think i have to use RenderTextures, i'm using them on a grid, so a single map could have over 40 or so
You could also just use one RenderTexture and do the grid separation in a logical step.

Reusing what already exists is good! :)
Official FAQ: https://www.sfml-dev.org/faq.php
Official Discord Server: https://discord.gg/nr4X7Fh
——————————————————————
Dev Blog: https://duerrenberger.dev/blog/