Netduino home hardware projects downloads community

Jump to content


The Netduino forums have been replaced by new forums at community.wildernesslabs.co. This site has been preserved for archival purposes only and the ability to make new accounts or posts has been turned off.
Photo

Out of memory issues


  • Please log in to reply
5 replies to this topic

#1 Rod Lopez

Rod Lopez

    Advanced Member

  • Members
  • PipPipPip
  • 33 posts
  • LocationSweden

Posted 29 March 2011 - 11:32 PM

Hi there,
This is my first post here, so please let me know if I am posting in the wrong place :)

So, as to the issue...
I have a setup where I am using one of the Netduino COMs as serial interface to an external chip (an IMU), communication works, and everything is fine and dandy (a.k.a I get my data through the serial), but I eventually (pretty much at predictable intervals) get an 'Out of Memory' error.
I honestly thought that moving to a managed framework meant that you didn't have to care about your memory anymore, is that true? do I need to release / dispatch memory blocks somehow? Do I need to manually invoke the garbage collector?
Could you give a look to the code and tell me if I am doing something terribly wrong?

thanks!!
-rod

IMUSerial = new SerialPort("COM1", 9600, Parity.None, 8, StopBits.One);
IMUSerial.DataReceived += new SerialDataReceivedEventHandler(IMUSerial_DataReceived);
IMUSerial.Open();

//write IMU code
Debug.Print("Serial is " + (IMUSerial.IsOpen? "open" : "not opened"));
byte[] pip = System.Text.Encoding.UTF8.GetBytes("r");

Debug.GC(true);
while (true)
{
	IMUSerial.Write(pip, 0, 1);
	Thread.Sleep(100);
	
}

static void IMUSerial_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
	byte[] buffer = new byte[10];
	IMUSerial.Read(buffer, 0, 10);
	String message = new String(System.Text.Encoding.UTF8.GetChars(buffer));
	Debug.Print(message);
}


#2 Mario Vernari

Mario Vernari

    Advanced Member

  • Members
  • PipPipPip
  • 1768 posts
  • LocationVenezia, Italia

Posted 30 March 2011 - 03:15 AM

I honestly thought that moving to a managed framework meant that you didn't have to care about your memory anymore, is that true? do I need to release / dispatch memory blocks somehow? Do I need to manually invoke the garbage collector?

About the memory automatic deallocation, by coming into the beautiful world of the managed code, you're in the heaven. The garbage collector do it for you, at least for the most common objects. There are some cases where you must deallocate manually an object, simply because is better having a deterministic destroy, instead waiting an unknown time for the GC.
Such a cases are, for example, sockets, files, input/output ports and others related with the physical layer.

If you meant "forget any problem of memory", that's true on a pc, having Gigs of ram. Here you have a bunch of Kib, so it is very common to see an exception for running out of memory. However the managed code eats much more ram than an equivalent native application.

Could you give a look to the code and tell me if I am doing something terribly wrong?

I don't see anything strange on your code.
The only issue you might have is about the serial incoming data rating. 9600 bps aren't an high speed, but if the incoming bytes are many more than the 10-byte buffer, probably the code is not able to empty the internal buffer.
As far I can see, your code sends a byte every 100ms, but how many bytes should receive within the same timeframe?
Cheers
Biggest fault of Netduino? It runs by electricity.

#3 demonGeek

demonGeek

    Advanced Member

  • Members
  • PipPipPip
  • 42 posts
  • LocationCanada

Posted 30 March 2011 - 05:12 AM

IMUSerial = new SerialPort("COM1", 9600, Parity.None, 8, StopBits.One);
IMUSerial.DataReceived += new SerialDataReceivedEventHandler(IMUSerial_DataReceived);
IMUSerial.Open();

//write IMU code
Debug.Print("Serial is " + (IMUSerial.IsOpen? "open" : "not opened"));
byte[] pip = System.Text.Encoding.UTF8.GetBytes("r");

Debug.GC(true);
while (true)
{
	IMUSerial.Write(pip, 0, 1);
	Thread.Sleep(100);
	
}

static void IMUSerial_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
	byte[] buffer = new byte[10];
	IMUSerial.Read(buffer, 0, 10);
	String message = new String(System.Text.Encoding.UTF8.GetChars(buffer));
	Debug.Print(message);
}


What happens if you move the buffer array up to the class level rather than creating a new instance each time the event fires?

#4 Rod Lopez

Rod Lopez

    Advanced Member

  • Members
  • PipPipPip
  • 33 posts
  • LocationSweden

Posted 30 March 2011 - 06:24 AM

What happens if you move the buffer array up to the class level rather than creating a new instance each time the event fires?

I get more or less the same result, it might take a bit longer (it is hard to say) but still runs out of memory at aprox the same pace.

The only issue you might have is about the serial incoming data rating. 9600 bps aren't an high speed, but if the incoming bytes are many more than the 10-byte buffer, probably the code is not able to empty the internal buffer.


I am pretty sure I am getting much more data than what I am consuming -through serialport.read-. I assumed it would be stored in the serial chip's memory and when full it would just drop new data. I'd make sense that, if an internal buffer expands with arriving data it would end up too big... I'll give that a shot and report back

#5 demonGeek

demonGeek

    Advanced Member

  • Members
  • PipPipPip
  • 42 posts
  • LocationCanada

Posted 30 March 2011 - 06:41 AM

I get more or less the same result, it might take a bit longer (it is hard to say) but still runs out of memory at aprox the same pace.



I am pretty sure I am getting much more data than what I am consuming -through serialport.read-. I assumed it would be stored in the serial chip's memory and when full it would just drop new data. I'd make sense that, if an internal buffer expands with arriving data it would end up too big... I'll give that a shot and report back


Try hooking the ErrorReceived event on the SerialPort and see if that provides more information. If you are overflowing the internal buffer it will generate an exception with the event type of RXOver.

#6 Rod Lopez

Rod Lopez

    Advanced Member

  • Members
  • PipPipPip
  • 33 posts
  • LocationSweden

Posted 11 April 2011 - 08:24 PM

It seems like it was as Mario suspected, if all the incoming data is not consumed with a read() call it'll just accumulate and start consuming RAM, until it runs out. I connected a callback to RXOver but never got called, I'll get back if I can get the experiment in the right setup again (you know how it when you need to break some things in order to fix others :)




0 user(s) are reading this topic

0 members, 0 guests, 0 anonymous users

home    hardware    projects    downloads    community    where to buy    contact Copyright © 2016 Wilderness Labs Inc.  |  Legal   |   CC BY-SA
This webpage is licensed under a Creative Commons Attribution-ShareAlike License.