|
|
| Author |
Message |
stevech
Joined: 23 Feb 2006
Posts: 657
|
|
Posted: 23 September 2006, 0:10 AM Post subject: demo code for RAM useage statistics |
|
|
Call this now and then in your application, during development, to see the dynamic memory allocation (e.g., for strings and temporaries) at work. And see if you are close to running out of RAM.
Don: looks correct?
| Code: | sub reportRAM()
console.writeline( _
" HeapEnd:&H" & cstrhex(Register.HeapEnd) _
& " EndStatics:&H" & cstrhex(register.ramStart + register.ramUsed) _
& " FreeRAM:" & cstr(Register.HeapEnd - (register.ramStart + register.ramUsed) ))
end sub |
|
|
| Back to top |
|
 |
dkinzer Site Admin
Joined: 03 Sep 2005
Posts: 2499
Location: Portland, OR
|
|
Posted: 23 September 2006, 0:25 AM Post subject: |
|
|
One element that is missing is the amount of stack space used in the Main() task. You've correctly noted that Register.RamStart + Register.RamUsed gives the end of statically allocated RAM and the beginning of the task stack for Main().
The stack for Main() and the low end of the heap grow toward each other. Register.UserSP, when referenced from the Main() task, would be the correct value to compare to Register.HeapEnd to determine how much headroom you have.
The code that checks for stack overflow compares the stack pointer for Main(), augmented by the stack margin, to Register.HeapEnd. On stack overflow, the processor is reset. |
|
| Back to top |
|
 |
stevech
Joined: 23 Feb 2006
Posts: 657
|
|
Posted: 23 September 2006, 2:02 AM Post subject: |
|
|
OK, I'm running amok here. This code has a function to measure the smallest amount of free RAM observed since the last reset. You can call it or let it be measured automatically by a ZBasic task, as shown below.
Also below is SampleLowWaterMarkRAM(). This is a task that's launched from main(). It checks the freeRAM every 100 miliseconds, as things happen in a multitasking environment, and as strings and other temporaries come and go within each task, even when main() is the only task.
-------------------------------------------------------
To use this sampling code:
1. Put this in your code where you declare global variables
dim lowWaterMarkRAM as unsignedInteger
dim SampleLowWaterMarkRAMstack(36) as byte
dim userSPmain as unsignedInteger
2. Put this in the beginning of main()
userSPmain = register.userSP
CallTask SampleLowWaterMarkRAM, SampleLowWaterMarkRAMstack
3. Optionally, in your deeply nested code, put in this line
n = freeRAM()
4. Wherever you wish:
debug.print "Low Watermark RAM:";cstr(LowWaterMarkRAM)
| Code: | sub SampleLowWaterMarkRAM()
dim n as unsignedInteger
lowWaterMarkRAM = &HFFFF ' set global variable
Do
n= freeRAM() ' mark free RAM
sleep(0.1) ' wait a while
loop
end sub
function freeRAM() as unsignedInteger
freeRAM = Register.HeapEnd - userSPmain ' userSPmain is written in the top of main()
if (freeRAM < lowWaterMarkRAM) then
lowWaterMarkRAM = freeRAM
end if
end function |
|
|
| Back to top |
|
 |
|