Memory Management

Last modified January 29, 2015

Table of Contents

Required

Tutorials:  First NETMF Project

Introduction

Many NETMF developers come from the PC world. They are used to writing code that runs fine on a PC but then they find that it will not run efficiently on an embedded device. The PC can be 3GHz with 4GB of RAM. NETMF devices often have less than 1% of the resources available on a PC.

With limited RAM, developers should only use what they really need. PC programmers tend to make a large buffer to handle the smallest task. Embedded developers study what they need and only allocate the needed memory. For a program reading data from UART, it can use a 100 byte buffer to read the data or a 1000 byte buffer; both work. While analyzing the code, it is noticed that it always reads about 40 bytes from UART in the main program loop. So its buffer should only ever be 40-50 bytes to save on space.

On some drivers, the NETMF system does a lot of buffering internally. For example, file system, UART, and USB drivers all have internal buffers in native code to keep the data ready until the developer uses the data from managed code. If we need a 1MB file, we do not need a large buffer at all. We create a small buffer and then send the data in chunks to the file system. To play a 5MB MP3 file, we only need 100 byte buffer that will read chunks from the file and pass them to the MP3 decoder.

Also avoid creating and freeing objects inside a loop or a frequently called function. It uses extra processor time to do so and can cause severe memory fragmentation that will cause the garbage collector to run often, resulting in a slow program.

Memory Reuse

The below example shows the optimal way to create and store objects. The SPI object is only created once. The buffer too is only created once instead of in each invocation of WriteRegister. Even though allocating the buffer inline like spi.Write(new byte[] { address, value }); may be more concise, it introduces a lot of memory fragmentation and is not suitable for frequently called code paths. This code requires the Microsoft.SPOT.Hardware assembly.

using Microsoft.SPOT.Hardware;

public class Program
{
	private static SPI spi = new SPI(new SPI.Configuration(Cpu.Pin.GPIO_NONE, false, 0, 0, false, true, 1000, SPI.SPI_module.SPI1));
	private static byte[] buffer = new byte[2];

	private static void WriteRegister(byte address, byte value)
	{
		buffer[0] = address;
		buffer[1] = value;
		
		spi.Write(buffer);
	}
  
	public static void Main()
	{
		for (byte i = 0; i < 255; i++)
			for (byte j = 0; j < 255; j++)
				WriteRegister(i, j);
	}
}
Leave feedback about this document.
Let us know if the information presented here was accurate, helpful and if you have any suggestions.
Leave feedback about this document.
Let us know if the information presented here was accurate, helpful and if you have any suggestions.

* Indicates required fields.
This form is only for feedback not support.
Review our how to find information guide on locating helpful resources.