Memory usage growth over time

The Partridge Family were neither partridges nor a family. Discuss.
User avatar
YoMomIsANiceLady
Posts: 33
Joined: February 2nd, 2017, 8:20 am

Memory usage growth over time

Post by YoMomIsANiceLady » February 23rd, 2017, 9:21 pm

Hello, so I'm testing my Snake game and if I run the program. Then go to task manager and check out Engine.exe, the RAM usage is constantly increasing at about 0.1MB every second. I wonder if there is an issue somewhere with my heap memory allocation or if that is normal?
"Life is like death, but completely different"
- Ivan Gašparovič

albinopapa
Posts: 4373
Joined: February 28th, 2013, 3:23 am
Location: Oklahoma, United States

Re: Memory usage growth over time

Post by albinopapa » February 23rd, 2017, 9:44 pm

Are you free'ing or delete'ing your memory that you allocate using malloc or new?

If you are using the 'new' operator to allocate memory, you should stop and switch to using std::unique_ptr.
If you think paging some data from disk into RAM is slow, try paging it into a simian cerebrum over a pair of optical nerves. - gameprogrammingpatterns.com

User avatar
YoMomIsANiceLady
Posts: 33
Joined: February 2nd, 2017, 8:20 am

Re: Memory usage growth over time

Post by YoMomIsANiceLady » February 23rd, 2017, 9:55 pm

I think I found my issue.
Here:

Code: Select all

void LetterMap::set(int widthIn, char* string)
{
    width = widthIn;
    map = new bool[widthIn*height];
    for (int i = 0; i < widthIn*height; ++i) {
        if (string[i] == '1') {
            map[i] = true;
        }
        else if (string[i] == '0') {
            map[i] = false;
        }
    }
}
This code gets called quite often.
I had a destructor written for it though

Code: Select all

LetterMap::~LetterMap()
{
    delete[] map;
}
It just doesn't seem to be called very often though.

Anyway, how would I go about transforming that to use unique pointers?
"Life is like death, but completely different"
- Ivan Gašparovič

cameron
Posts: 794
Joined: June 26th, 2012, 5:38 pm
Location: USA

Re: Memory usage growth over time

Post by cameron » February 23rd, 2017, 10:29 pm

I agree unique/shared ptrs should be used if you just deallocate the memory in the normal flow(when your done with it). However, I have encountered some cases where I need to delay deallocation for performance reasons. Moral of the story I guess, use unique ptrs if want to dealloc when it goes out of scope(most cases).

Anyways:
#include <memory>
std::unique_ptr<type>(new Type) or
std::unique_ptr<type> name = std::make_unique<type>(new Type)
Computer too slow? Consider running a VM on your toaster.

User avatar
YoMomIsANiceLady
Posts: 33
Joined: February 2nd, 2017, 8:20 am

Re: Memory usage growth over time

Post by YoMomIsANiceLady » February 24th, 2017, 12:08 am

Okay I tried using unique pointers but it is just so iffy to work with them if you need to make an array of which size changes on runtime. Which is exactly what I needed. Maybe it's not that tricky but I found it confusing. I tried to find where i was making the mistake of not deleting properly and I got it!

Basically I had this issue

Code: Select all


{
    LetterMap letterCode;

    for(int i = 0; i < x; ++i) {
        letterCode.set();
    }

}

So the set() function allocates memory. But the destructor gets called only once at the end of the scope. Which means that memory was allocated X times but only deleted once. I fixed the issue by declaring the LetterCode variable inside the for loop:

Code: Select all


{

    for(int i = 0; i < x; ++i) {
        LetterMap letterCode;
        letterCode.set();
    }

}

Now the destructor gets called on every loop iteration
"Life is like death, but completely different"
- Ivan Gašparovič

MrGodin
Posts: 721
Joined: November 30th, 2013, 7:40 pm
Location: Merville, British Columbia Canada

Re: Memory usage growth over time

Post by MrGodin » February 24th, 2017, 1:33 am

oops .. :D
Last edited by MrGodin on February 24th, 2017, 1:35 am, edited 1 time in total.
Curiosity killed the cat, satisfaction brought him back

User avatar
chili
Site Admin
Posts: 3948
Joined: December 31st, 2011, 4:53 pm
Location: Japan
Contact:

Re: Memory usage growth over time

Post by chili » February 24th, 2017, 1:33 am

I agree that unique_ptr is the way to go most times. But as a beginner, it is also a good experience to understand how to properly setup memory allocation / deallocation for a number of reasons I believe. It teaches you a lot of fundamental concepts. Once you understand it and can reliably do it, I'd say try to never do it again and just use smart pointers, containers, etc. whenever possible :P


For your code, that calls 'new', but where is the corresponding delete?

EVERY new must have a corresponding delete. Defining a destructor will define WHAT happens when memory is deleted, but it will not actually initialize the deletion.

the destructor you define will be called only once when the lettermap itself is destroyed, but if you call set multiple times and keep assigning new memory blocks to the map member, you lose the handle on whatever that was pointing to before, and thus you are leaking memory like a sieve bro! :lol:
Chili

User avatar
YoMomIsANiceLady
Posts: 33
Joined: February 2nd, 2017, 8:20 am

Re: Memory usage growth over time

Post by YoMomIsANiceLady » February 24th, 2017, 2:27 am

Yeah, I don't know how I should resolve the problem. Should I maybe make some sort of a function that releases the pointers? And call it after I'm done with setting it? Maybe I could limit the use of set() to once per object lifetime?

OR... I could first release pointers when set is called? I guess that should do it. I first delete and then call new. After I deleted the old ones?
"Life is like death, but completely different"
- Ivan Gašparovič

User avatar
chili
Site Admin
Posts: 3948
Joined: December 31st, 2011, 4:53 pm
Location: Japan
Contact:

Re: Memory usage growth over time

Post by chili » February 24th, 2017, 2:40 am

in constructor, set map = nullptr or new .... (don:t leave uninitialized)

in set

check if map == nullptr

if not, delete [] map

map = new ...

in destructor

check if map==nullptr

if not, delete [] map
Chili

User avatar
YoMomIsANiceLady
Posts: 33
Joined: February 2nd, 2017, 8:20 am

Re: Memory usage growth over time

Post by YoMomIsANiceLady » February 24th, 2017, 5:46 am

Yeah, that makes sense and works perfectly! Thanks chili <3

There's one thing I don't understand though. Why would you check in destructor? Does it matter if you check or not? Can't you just delete anyway? Even if it's a nullptr?
"Life is like death, but completely different"
- Ivan Gašparovič

Post Reply