Resource saving by using timers instead of threads

Hi,

got a resource problem and am constantly running out of memory on my Panda II.

i took the easy route, by creating a thread for each sensor i use, to read data and save it to a file.
now i am wandering if this “easy” way may have been the wrong path that i have taken.

There can be a user specified number of sensors (of different types - analog, I2C, onewire)
and each can have a different time interval in which they are scanned, so it has to be somewhat dynamic.
has anyone tries using timers to get rid of threads, or do they use just as many resources?
if for example a sensor needs to get scanned every 5 seconds, then i use sleep in between reads.
if i set up a timer, which calls the callback function every 5 seconds, then i could theoretically achieve the same logic and may save resources
in my case it does not matter if the scan time variation is 100 ms or so.

has anyone tried this?
would like some user input before ripping the app apart :wink:

any comments are appreciated.

Until I had a detailed understanding where the memory resources are being used I would not change from threads to timers.

With resource problems, on small memory devices, it is hard to recommend what to change. That is why I say that a detailed understanding of memory use is required.

hi Mike,

thanks for the quick reply.

detailed understanding where the memory resources are being used
how can i do this?
all i have been able to find is the GC output which does not help that much.

the app is pretty complex and interacts between different modules/threads, so it is pretty difficult to just use portions of it.

every area, such as analog sensors, oneWire stuff, … has their own assembly.
as not all modules are always needed - eg. a user might not need I2C - i have started dynamically loading these now, but i have noticed that i loose the ability to debug into the assemblies, which makes it difficult to locate problems :wink:

i currently have quiet a bit of debug info in the code, including text which shows which function it has been called from.
wander if it would make sense to load the static text part from the resource?
or does the resource file get loaded completely at runtime as well?

the app also runs on the netduino P2 included added resources, such as networking and webServer without any issues, but it has a lot more ram.

unlikely you are running short of flash, so the program size is not an issue.

threads will take memory with their stack.

have you looked for tables that can be released after use?

it is possible the total app is too big for panda.

unlikely you are running short of flash
the flash is fine. the app is just over 100K.
when running with all assemblies loaded, then it comes close to the max ram, by about 3-4K.

have you looked for tables that can be released after use?
i set all class objects to null when not required any more, unless they leave the scope of the function.
the main loop runs the GC every 3 seconds.

if memory intensive stuff is happening, like dynamically loading the assembly for config, then right after it is done running, i dispose of all used objects, set them to null and call GC.

threads will take memory with their stack.
that was the reason for asking how much more efficient the timers are.
from what info i could find out, a timer is handled by the thread pool and only 1 thread is used for all timers.
in theory, this should save a bit of memory, when using 7 sensors.

it is possible the total app is too big for panda.
hope not.
that would make this board useless to me (and others when the app is done) which i am not willing to accept.

@ 366Cobra - one more thing you could try is to break your project up into smaller sub-projects under the same solution. The loader seems to do better with multiple smaller assemblies rather than one big assembly. There was a post on this subject a long time ago…

@ jasdev
i am already doing this.
analog sensors, oneWire, I2C and so on have their own assemblies, which i am currently loading dynamically.

if the config file does use I2C, then it is not being loaded.
problem is not being able to debug into dynamically loaded assemblies.
or have i missed something?

is there a tool that can spy on where the memory is being used?
GC is not too informative.

@ 366Cobra - I am not sure where assemblies loaded dynamically are executed versus including them in the program image. I would assume, but could be wrong, that dynamically loaded assemblies go into memory versus the program image which in in flash. If this is true, dynamically loading assemblies is not a good solution for reducing memory usage.

@ Mike

I am hoping that the program image including all embedded resources (my assemblies) are being saved to flash.
when run, the needed modules get loaded into ram and when an assembly is being loaded, it should also get transferred into ram.
if that is not the case, then the framework has a serious design flaw - well, in my opinion anyway. MS would probably call it a feature :wink:

One thing i have noticed, that the compiler (VS2010) is not intelligent enough to remove not needed assembly references.
Had code at some stage, that was 130Kb in size when deployed and when removing references which were not needed, it sank to just over 100Kb.

a quick note.

have also loaded the assemblies from the SD card.
downside is that they assemblies have to be transferred onto the SD after a change and later on, there could be a version mismatch, if the user chooses the wrong assembly.

@ 366Cobra - ReSharper: The Visual Studio Extension for .NET Developers by JetBrains has a nice option to remove unused references