#34870 - gadget - Thu Jan 27, 2005 4:03 pm
Is there anyone to detect memory usage? I'm trying to keep the number of uninitialized variables down as well as avoiding use of malloc/free because there's no way I've found to track the amount of memory i'm allocating at runtime.
Has anyone found a way to track this, or is creating my own memory manager the only way to go?
#34876 - poslundc - Thu Jan 27, 2005 5:26 pm
If you're using GCC, then you can use the nm utility with the "-n" switch on your .elf file to display all of your globally allocated variables along with their addresses, in the order they appear in memory. Using this you can roughly tabulate how much IWRAM you are using.
Dynamically-allocated memory is much more difficult to track. There are tricks you can use such as putting a conspicuous pattern at a certain memory location and checking to see if it's still there during runtime, or you can override malloc/new/whatever with a debug mode that lets you track memory usage. On the whole it's usually more trouble than it's worth, I find.
Dan.
#34917 - Joat - Fri Jan 28, 2005 6:02 am
The linker option map will generate a map of where all the compiled stuff goes, including code, uninitialized data, and initialized data.
Err, it something along the lines of adding -Wl,-Map,filename.map
Check your build directory, most of the standard makefiles floating around should already generate a map file (and if not, why not!)
For malloc/free, you can wrap them (and it makes it easier to create your own memory manager later, which you may want to do). Something along the lines:
size_t dynamicMemoryUsage;
void * engineMalloc(size_t size) {
dynamicMemoryUsage += size;
return malloc(size);
}
engineFree is a bit harder to do, you can either pass in the size (which could complicate your calling code if you don't normally keep the size around), or do some non-portable code to look at the allocation record (if someone knows a portable way of getting the size of malloc'd memory, I'd love to know). I'm drawing a blank right now as to how newlib manages its allocation records, but it could be something as simple as:
dynamicMemoryUsage -= *(((uint32 *)ptr) - 1); // THEORETICAL
This will give you an *idea* of dynamic memory usage. Memory managers involve overhead in the form of allocation records, and wasted space in the form of fragmentation from repeated allocs/frees, so this count isn't perfect (another reason why your own memory manager can be good, since you can track exact usage, and fragmentation, and could e.g. do a full reset at certain points, like between levels, where you copy any really needed information to a static buffer, and kill all of the alloc records, to prevent a potential eventual crash).
Writing your own memory manager certainly isn't necessary, just something to keep in mind.
_________________
Joat
http://www.bottledlight.com
#34932 - sasq - Fri Jan 28, 2005 9:11 am
Checking memory used by the elf is simple, just do:
arm-elf-objdump -t myprogram.elf | sort > memory.txt
from a dos-prompt and you have a sorted list of all static memory usage.
For a malloc wrapper something like this is pretty convinient;
Code: |
int alloc_total = 0;
typedef struct
{
int line;
char *file;
int size;
int padding; // Make sure its 16bytes long = aligns well
} AllocInfo;
void *debug_malloc2(int size, char *file, int line)
{
AllocInfo *a = malloc(i+sizeof(AllocInfo));
a->line = line;
a->file = file; // Safe because indata is always static
a->size = size;
alloc_total += size;
return (void *)&a[1];
}
void *debug_free(void *p);
{
AllocInfo *a = &((AllocInfo *)p)[-1]
alloc_total -= size;
free((void*)a);
}
#define debug_malloc(i) debug_malloc2(i, __FILE__, __LINE__)
|
You should also add and remove the AllocInfo-structures to a list so you can dump the current memory usage at any time in the program, and keep track of memory leeks, and exactly where they occured.
Or instead of a list you could make a hash-value from the filename and line-number and have an array of memory allocated for each file/line.
#35168 - gadget - Mon Jan 31, 2005 4:56 pm
Thanks, i'll try these suggestions and see what I can do with them. :)