Dynamic memory allocation - stability issues


brianv

Recommended Posts

I've been making some updates to the RetroCade codebase.  I pulled down a Queue class from the Arduino code gallery and made a few modifications to it. I am having some stability issues after a bunch of new/delete operations, I get a hard crash and the Papilo freezes.  I've done some troubleshooting, but as far as I can tell I don't have any memory leaks.

 

To shed some light on what's going on, I added two global variables: one for allocations and one for de-allocations.  These are incremented and decremented with each operation.  I dump these values out to the console periodically and haven't detected any memory leaks.  In my particular case there are at most 3 dynamically allocated objects at a given time. The alloc/dealloc counts  are exactly what I am expecting: If I have 303 allocs then deallocs would be somewhere between 300-302.  

 

tldr;

 

Do I need to do anything other than call delete to ensure dynamically allocated memory is freed up?

Is it preferable to use C-style allocation/deallocations for applications like this?

Can anyone recommend any profiling tools I can run to help me track down memory issues?

Since I know the maximum amount of memory I will ever need ahead of time, would it be better to create a statically allocated pool of objects and pull them out of the pool when needed instead of dynamically allocating memory?

 

Thanks,

 

Brian

Link to comment
Share on other sites

It is more than likely that free doesn't actually free any memory depending on how it is implemented, embedded development usually doesn't use dynamic memory due to the heavily limited RAM available, if the queue contains fixed size elements I would suggest using a Pool allocator since they are relatively easy to implement and deal well with small fixed sized objects that get deallocated a lot.  In answer to your question, yes a pool would be much better, or simply preallocate the queue or whatever to the size you need.

 

I would suggest finding the implementations of malloc and free that are used and determining how they do their allocation.

Link to comment
Share on other sites

I've been making some updates to the RetroCade codebase.  I pulled down a Queue class from the Arduino code gallery and made a few modifications to it. I am having some stability issues after a bunch of new/delete operations, I get a hard crash and the Papilo freezes.  I've done some troubleshooting, but as far as I can tell I don't have any memory leaks.

 

To shed some light on what's going on, I added two global variables: one for allocations and one for de-allocations.  These are incremented and decremented with each operation.  I dump these values out to the console periodically and haven't detected any memory leaks.  In my particular case there are at most 3 dynamically allocated objects at a given time. The alloc/dealloc counts  are exactly what I am expecting: If I have 303 allocs then deallocs would be somewhere between 300-302.  

 

tldr;

 

Do I need to do anything other than call delete to ensure dynamically allocated memory is freed up?

Is it preferable to use C-style allocation/deallocations for applications like this?

Can anyone recommend any profiling tools I can run to help me track down memory issues?

Since I know the maximum amount of memory I will ever need ahead of time, would it be better to create a statically allocated pool of objects and pull them out of the pool when needed instead of dynamically allocating memory?

 

Thanks,

 

Brian

 

Hey Brian,

 

Alvie put together a quick and dirty way of doing malloc on the ZPUino so I could access the memory. But it is not well tested and there is no corresponding free method to go along with it. It is just a pointer to the top of memory space that gets increased every time you call it. Free is just a blank function right now, it does nothing... It is best to use statically allocated objects. I'm not sure if Alvie has any plans to make a more robust version of malloc and free, there hasn't been much of a demand so far, we can ask him though.

 

The other thing to watch out for, if you get large case statements you will start to see odd behavior. If you move most of the code in the case statements to functions and have the case statements just call the function that will clear it up. Alvie warned me about it during development, it seems to be a bug with gcc.

 

Jack.

Link to comment
Share on other sites

Hi brianv,

 

Indeed Jack is right: the current allocator only grows up. The reason for this is that malloc() and similar take too much code space and memory for most kind of applications.

 

Note that also most RTOS do not allow dynamic alocations either.

 

What I suggest you doing is some sort of bitmap allocator for your objects, but that will only work if your objects are fixed size. Is this the case ? For non-fixed size, remember that memory fragmentation is a real issue without a MMU.

 

You can also pull the standard "C" malloc() into play, it will also work for new/delete operators. Note that codespace will increase a lot, and will make you application run significantly slower (malloc is very very slow).

 

Alvie

Link to comment
Share on other sites

Thanks for the info guys, definitely good to take into consideration for future development. The clear answer  for this  case is to witch the code over to use a fixed-size pool/buffer since the maximum amount of memory needed is a known quantity.  I think doing this will pare down the amount of ROM used as well.

 

Brian

Link to comment
Share on other sites

But are your "items" all the same size, meaning, do you want to allocate fixed size blocks (like always malloc(32)  ?)

 

In case you want a simple Queue, you can try using the <cbuffer.h> I wrote, it supports any kind of structures (if they are constant in size).

 

Here's some information regarding bitmap allocators:

 

https://eatplayhate.wordpress.com/2010/09/04/memory-management-from-the-ground-up-2-foundations/

Link to comment
Share on other sites

But are your "items" all the same size, meaning, do you want to allocate fixed size blocks (like always malloc(32)  ?)

 

In case you want a simple Queue, you can try using the <cbuffer.h> I wrote, it supports any kind of structures (if they are constant in size).

 

Here's some information regarding bitmap allocators:

 

https://eatplayhate.wordpress.com/2010/09/04/memory-management-from-the-ground-up-2-foundations/

 

Alvie,

 

Thanks for the links. The CBuffer code you wrote is pretty slick, but I wanted a data structure that would allow to remove items from the middle of a list.  In the end I switched the Linked List/Stack over to used a fixed size buffer of ListNodes.  It's stable now, haven't seen any crashes since I made the update.

 

Brian 

Link to comment
Share on other sites

Archived

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