Main Site Documentation

Memory leakage in my code?


#1

Hello

I am issuing a lot of : Exception System.OutOfMemoryException - CLR_E_OUT_OF_MEMORY during the application I am attempting to develop.

The GC info gives the following:

The line I want to add is a string (usually less than 200 characters).

Do you have any idea on how to solve this issue? where should I start and how to read the GC data printed during execution?


#2

Before you allocate relatively-large objects, add this code to compact your heap, Debug.GC(true)


#3

Hello GUS and thank for this fast answer.

I used to force GC runs when I have such errors but I finally decided to remove them all due to no improvements.

One question about Debug.GC(true); Is it a blocking instruction? I mean are we sure that the memory is cleaned before the following instruction?

For now I have rewritten Debug.GC(true) before the StreamWriter instanciation. Is that correct?:


#4

Gus…

I would think that if memory is fragmented, and garbage collection is required, it would automatically be invoked.

GC for memory issues is not “good practice”.

I suggest the OP look at his overall use of memory and try to optimize for an embedded environment. He is getting close to running out of memory, and unless the program will be finished with the resolution of the current issue, there will be more memory problems to come.


#5

Good question. This is automatically invoked when system is idle, like it is on PCs (big framework) but on embedded systems, the system is never idle in most cases. Plus it is a must have on an embedded system. This was suggested to Microsoft before but didn’t make it to the release but IIRC this is finally added to NETMF 4.2

And yes, you will need to optimize your code so you are not pushing your system to the limits. It is a dynamic and managed system so it is easy to allocate things only when you need them.


#6

“It is a dynamic and managed system so it is easy to allocate things only when you need them”

Yes, that is one of the best features of MF and unless one is careful, one of the most dangerous.

I have worked on embedded systems which did not have the ability to dynamically allocate memory. You had to allocate memory at compile time. It made the developer think about memory use and optimization.

MF and the fast FEZ processor allow the developer to typically not think about memory issues, but on larger projects, this can lead to problems which are difficult to fix.

A famous engineer, in an ebook on FEZs, once said “think small”.


#7

Your app is “massive” relatively speaking. There’s only 62kb available total and 10k left by the time you call the Streamwriter. Streamwriter will allocate 4k even if you are only writing 200 bytes and it can’t.

Try some of the following to get to at least 20k free before using Streamwriterband reader:

Avoid large static arrays unless you reuse them often.
Don’t declare fields or or global variables hanging around with nothing in them. They still take up space.
Your classes look big. Do you have arrays or large buffers in them?
This a pain but put Debug.GC(true) everyhere and follow how memory is used and released. Maybe it will show you the culprit. If you are low on memory on startup then you need to look at your app architecture.

Maybe post some code to have a look at.

Rudie


#8

Many thanks for your answer.

Here are the facts:
The app is about 98kB ( value given by Visual Studio when deploying the app)
It parses a txt file on the SD card and according to the configuration of that file, it logs on SD files a lot of events coming from analog, digital and 2 com port input.

I started to rewrite the famous Debug.GC(true) everywhere in the app to locate where is the leakage. It gives at least some indications about where to be focused on.

The weird thing is that running two times the same application doesn’t crash at the same place (however it runs out of mem before logging anything and when launch on visual it crashes when parsing the txt file)

Furthermore, is anyone can explain me why the application seems to run better on its own than when launch by Visual (in release mode). Is that related to deugging stuffs?

Finally do you know if there’s a good profiling tool abble to handle netmf and c#?

Again many thanks for your interest in this post


#9

The size you see is flash not ram I think. What assemblies are added to your project? Cam you show a dump of bootup messages?


#10

@ leforban: Also, try not to create variables inside a loop like this:


for(int i=0;i<100;i++)
{
string b; //Bad, it will recreate a new b with every loop and the garbage collector will not have time to clean up.
b="A"
}


#11

Hello Gus

Here is a dump of boot up message:

One question about the use of string[]: When parsing the txt file the app makes an intensive usage of same kind of functions like the following one:

[quote]private void SCR_dec_M(string p_ligne)
{
string[] SplitLine = p_ligne.Split(new char[] { ’ ’ });
SCR_etat.Copy_Mode = SplitLine[1];
SCR_etat.Copy_Methode = SplitLine[2];
SplitLine = null;
}[/quote]
For each line of my txt file, such kind of function is call. Should I declare Splitline as a global variable?
What is the impact of [quote]SplitLine=null; [/quote], I mean does this instruction allows the GC to clean it properly?

Finally I discovered that there is too memory allocated for StreamReader.Readline. According to what i read, the allocated buffer is 8K (4K + 4K for growing size). If I understand well the bug has been declared in codeplex and should be fixed in NETMF 4.2. Do you know when this release will be available?

For now I have tried to use the String.ReadlineEx that is available on the forum. Unfortunately Visual Studio tells me that “Deployment to the device was not successful.” It seems that this is due to the size of the overall assemblies (98512 bytes versus 98256 bytes before).
If I succeed to clean up some part of code to decrease the size down to 98256 bytes (it was deploying succesfully for this size) do you think this can be reliable solution before the next NETMF release?


#12

Sorry, I am lost with multiple questions. Let us cover one thing at a time.

The dump is not complete, I am trying to see what assemblies you have in your projects? Maybe you are adding ones you do not need like tinycore?


#13

Hello GUS

I’ve modified the code to make it lighter and uses now the ReadlineEx function that we can find on the forum that solve (at least) the Out of Mem for the readline function. I moved back to a 4.1.5.0 firmware to succeed the deployment other the app is too big and can’t be deployed on the device.

Now the app seems more reliable but I need more time to test it.

When you talk about linked assemblies, do you mean the references that we need to add to the VS project? To be sure about how to list them, what do you need? a dump of deployement? a screenshot of the added references?


#14

Screenshot is fine


#15

Hello Gus, here’s the screenshot of the references added to the project. Hope it will help…


#16

Those look okay so that is not causing any extra memory usage.


#17

Ok this is also good for me, and if I remove on of these assemblies, there’s some errors in compilation.

Let’s go back to my list of question if you agree:

Does the deployment under Visual Studio (meaning launching the app through the green arrow of VS) consumes more memory than if the app runs as standalone app? I run the app as a standalone one all the night without rebooting (a watchdog is set up) whereas when the app runs through VS, I see some “out of memory exception” and the application restart with the watchdog meaning that something wrong occurs

In the output screen under VS, I see that there’s memory allocated for debugging purpose (about 2080 bytes if I remember well)


#18

Yes debugging requires very little resources and the device runs very slightly slower when debugging. Nothing that you would normally be concerned of but you have a large app that is pushing the limits. I still can’t see how your application is suing all memory and there is no room to optimize things.

Add this at the very beginning of your code, right in “main” Debug.GC(true) and show us the output please.


#19

A lot of Debug.Print() statements could make a difference in peak memory usage between teathered and standalone operation.

If your are so close enough to memory exhaustion that standalone operation makes a difference, then you need to optimize your code.


#20

Dear all, all the Debug.print have already been removed.

I will put the Debug.GC(true) at the beginning and will let you know.

Regards…