Memory usage growth over time
- YoMomIsANiceLady
- Posts: 33
- Joined: February 2nd, 2017, 8:20 am
Memory usage growth over time
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č
- Ivan Gašparovič
-
- Posts: 4373
- Joined: February 28th, 2013, 3:23 am
- Location: Oklahoma, United States
Re: Memory usage growth over time
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 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
- YoMomIsANiceLady
- Posts: 33
- Joined: February 2nd, 2017, 8:20 am
Re: Memory usage growth over time
I think I found my issue.
Here:
This code gets called quite often.
I had a destructor written for it though
It just doesn't seem to be called very often though.
Anyway, how would I go about transforming that to use unique pointers?
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;
}
}
}
I had a destructor written for it though
Code: Select all
LetterMap::~LetterMap()
{
delete[] map;
}
Anyway, how would I go about transforming that to use unique pointers?
"Life is like death, but completely different"
- Ivan Gašparovič
- Ivan Gašparovič
Re: Memory usage growth over time
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)
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.
- YoMomIsANiceLady
- Posts: 33
- Joined: February 2nd, 2017, 8:20 am
Re: Memory usage growth over time
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
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:
Now the destructor gets called on every loop iteration
Basically I had this issue
Code: Select all
{
LetterMap letterCode;
for(int i = 0; i < x; ++i) {
letterCode.set();
}
}
Code: Select all
{
for(int i = 0; i < x; ++i) {
LetterMap letterCode;
letterCode.set();
}
}
"Life is like death, but completely different"
- Ivan Gašparovič
- Ivan Gašparovič
Re: Memory usage growth over time
oops ..
Last edited by MrGodin on February 24th, 2017, 1:35 am, edited 1 time in total.
Curiosity killed the cat, satisfaction brought him back
Re: Memory usage growth over time
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
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!
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!
Chili
- YoMomIsANiceLady
- Posts: 33
- Joined: February 2nd, 2017, 8:20 am
Re: Memory usage growth over time
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?
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č
- Ivan Gašparovič
Re: Memory usage growth over time
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
in set
check if map == nullptr
if not, delete [] map
map = new ...
in destructor
check if map==nullptr
if not, delete [] map
Chili
- YoMomIsANiceLady
- Posts: 33
- Joined: February 2nd, 2017, 8:20 am
Re: Memory usage growth over time
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?
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č
- Ivan Gašparovič