Small C# program takes up too much memory

E

elty123

I have a small C# program (about 400 lines of code) that is only 28kb
after compiled.

However when it runs (takes a whole 5 seconds) it takes up nearly 20MB
of memory and I don't see why.

Some of the assembly I used:

using System;
using System.Collections.Generic;
using System.Windows.Forms;
using System.Xml.Serialization;
using System.IO;
using System.Diagnostics;
using System.Management;

The program read (de-serialize) a XML file, then generate a list. Then
the program read through the event log and see if anything match the
list.

Is there anyway I can reduce the memory usage?
 
T

Tom Porterfield

I have a small C# program (about 400 lines of code) that is only 28kb
after compiled.

However when it runs (takes a whole 5 seconds) it takes up nearly 20MB
of memory and I don't see why.

Some of the assembly I used:

using System;
using System.Collections.Generic;
using System.Windows.Forms;
using System.Xml.Serialization;
using System.IO;
using System.Diagnostics;
using System.Management;

The program read (de-serialize) a XML file, then generate a list. Then
the program read through the event log and see if anything match the
list.

Is there anyway I can reduce the memory usage?

That is nearly impossible to answer without additional information. But
let's start by getting rid of the irrelevant information. The number of
lines of code, and the size of the compiled assembly, are meaningless here.
I could have a program that was but a few lines of code, but that code
loaded a 100 MB file into memory. The runtime memory requirements for the
program would then be quite large compared to the size of the executable,
but it's a pointless comparison. How much data is in your XML file? What
is in the generated list? What type of list is it? How are you processing
the event log?
 
M

Morten Wennevik [C# MVP]

Hi,

You can memory profile .Net applications using Task Manager because .Net applications do not necessarily use the memory they appear to be using. For instance, if the system is running low on memory, the Garbage Collector will free discarded objects much faster than a on a system with plenty of spare memory. There are tricks to force only the necessary amount of memory to run the application show up in task manager, but it will lead a slower program and serves no purpose.

Remember that your application may be small, but it uses quite a few other classes that needs to be loaded into memory as well. For instance the Form class your application inherits from.

Stop worrying about the memory, and don't forget to Dispose() and Close() objects that have implemented those methods. Typically streams and resources.
 
M

melon

That is nearly impossible to answer without additional information. But
let's start by getting rid of the irrelevant information. The number of
lines of code, and the size of the compiled assembly, are meaningless here.
I could have a program that was but a few lines of code, but that code
loaded a 100 MB file into memory. The runtime memory requirements for the
program would then be quite large compared to the size of the executable,
but it's a pointless comparison. How much data is in your XML file? What
is in the generated list? What type of list is it? How are you processing
the event log?

The XML file is 6KB. The list itself has about 20 objects in total in
a nested generic list. Each of the object consist of about 10 string
(around 20 characters each) and a few int. In C the entire list is
probably less than 10KB of memory.

The event log is accessed with EventLog eLog = new EventLog("System")
I go through each of them in a
foreach loop. The size of the event log is at default, 512KB.

The program used 3 reader/writer streams, and I close them
afterwards. The number of streams does not really affect the memory
size, as the program consume as much memory with 1 streams or 3
streams.
 
I

Ignacio Machin \( .NET/ C# MVP \)

Hi,

I have a small C# program (about 400 lines of code) that is only 28kb
after compiled.

However when it runs (takes a whole 5 seconds) it takes up nearly 20MB
of memory and I don't see why.

IIRC the minimun memory footprint of a win app is around 16 MB. Take a look
into the archives, this kind of question is posted from time to time
 
W

Willy Denoyette [MVP]

Chris Mullins said:
I have a small C# program (about 400 lines of code) that is only 28kb
after compiled.

However when it runs (takes a whole 5 seconds) it takes up nearly 20MB
of memory and I don't see why.
[...]

Is there anyway I can reduce the memory usage?

This is a pretty common problem. Fortunatly there's a pretty easy solution:

http://www.coversant.net/dotnetnuke/Default.aspx?tabid=88&EntryID=4


Chris,
you don't want your applications to run under an administrator account just to fake low
memory consumption do you?
Note that doing this is much worse than calling GC.Collect in .NET, all it does is disturb
the OSses BalanceSet Manager without any benefit for the user.

Willy.
 
C

Chris Mullins [MVP]

While I agree with you 100% on every technical level, the user's perception
defines reality. Users see the big number in task manager and get cranky.
They see a small number, they're happy.

I really wish I had a better answer. For almost all the small client-side
stuff we do, this works well. Especially as these apps load, and don't
really do anything. They're doing almost no processing, no data base stuff -
they're just sitting idle and reporting that they're taking 20-50 megs of
memory.

Running GC.Collect over & over doesn't even solve the problem - the app
still reports a huge amount of memory, and the users perception then is that
we suck.

Please - give me a better solution! :)

--
Chris Mullins, MCSD.NET, MCPD:Enterprise, Microsoft C# MVP
http://www.coversant.com/blogs/cmullins

Willy Denoyette said:
Chris Mullins said:
I have a small C# program (about 400 lines of code) that is only 28kb
after compiled.

However when it runs (takes a whole 5 seconds) it takes up nearly 20MB
of memory and I don't see why.
[...]

Is there anyway I can reduce the memory usage?

This is a pretty common problem. Fortunatly there's a pretty easy
solution:

http://www.coversant.net/dotnetnuke/Default.aspx?tabid=88&EntryID=4


Chris,
you don't want your applications to run under an administrator account
just to fake low memory consumption do you?
Note that doing this is much worse than calling GC.Collect in .NET, all it
does is disturb the OSses BalanceSet Manager without any benefit for the
user.

Willy.
 
T

Tom Porterfield

Chris said:
While I agree with you 100% on every technical level, the user's
perception defines reality. Users see the big number in task manager and
get cranky. They see a small number, they're happy.

I really wish I had a better answer. For almost all the small client-side
stuff we do, this works well. Especially as these apps load, and don't
really do anything. They're doing almost no processing, no data base
stuff - they're just sitting idle and reporting that they're taking 20-50
megs of memory.

Running GC.Collect over & over doesn't even solve the problem - the app
still reports a huge amount of memory, and the users perception then is
that we suck.

Please - give me a better solution! :)

Believe it or not, when I ran into that I actually took the approach of
education the user. It took a bit and not all go it, but most did and I no
longer heard complaints on this.
 
T

Ted E.

I have to agree with Ignacio. I wrote a small program to download two
files from the internet and save them to hard drive. The whole code,
including two comments and 4 assemblies used is 22 lines - only 10 lines
of which I added. The executable is only 16K but when I run it, I can
watch the memory run up to just a bit under 10MB.
 
W

Willy Denoyette [MVP]

Chris Mullins said:
While I agree with you 100% on every technical level, the user's perception defines
reality. Users see the big number in task manager and get cranky. They see a small number,
they're happy.
So you mean that:
- all of your users run with administrative privileges, and..
- as such, they know what "Memory Usage" ("Working Set" on Vista) really means or what
"Private Bytes" is all about.
Why do they "get cranky" then?
If they don't know exactly what these counters are about, why are they looking at them and
why do they "get cranky" then?
I really wish I had a better answer. For almost all the small client-side stuff we do,
this works well. Especially as these apps load, and don't really do anything. They're
doing almost no processing, no data base stuff - they're just sitting idle and reporting
that they're taking 20-50 megs of memory.

Running GC.Collect over & over doesn't even solve the problem - the app still reports a
huge amount of memory, and the users perception then is that we suck.

I didn't say that GC.Collect was a solution, I said that both are bad, calling GC.Collect at
regular basis disturbs the GC operations, applications that are reducing the WS disturbs the
BalanceSet Managers normal operations and is even worse as the BSM is a global resource. In
both cases let them do their job, both the GC and certainly the BSM know better than anyone
else when they should run.

But again, this is not the real issue, you are forcing your users to run as full admins (a
big NO NO per default on Vista) which makes them vulnerable to all sort of security attacks,
this is what I call *reality*, tell them about this and let them make an educated choice.
Please - give me a better solution! :)

I don't see a problem (other than running as an administrator), so why asking for a solution
:)

Willy.
--
Chris Mullins, MCSD.NET, MCPD:Enterprise, Microsoft C# MVP
http://www.coversant.com/blogs/cmullins

Willy Denoyette said:
Chris Mullins said:
I have a small C# program (about 400 lines of code) that is only 28kb
after compiled.

However when it runs (takes a whole 5 seconds) it takes up nearly 20MB
of memory and I don't see why.

[...]

Is there anyway I can reduce the memory usage?

This is a pretty common problem. Fortunatly there's a pretty easy solution:

http://www.coversant.net/dotnetnuke/Default.aspx?tabid=88&EntryID=4


Chris,
you don't want your applications to run under an administrator account just to fake low
memory consumption do you?
Note that doing this is much worse than calling GC.Collect in .NET, all it does is
disturb the OSses BalanceSet Manager without any benefit for the user.

Willy.
 
C

Chris Mullins [MVP]

Willy Denoyette said:
So you mean that:
- all of your users run with administrative privileges, and..

Well, most do. They're not even our users. They're users at large
enterprises around the world. We don't mandate it, and if they're not
running as an Admin, we have to work there too.
- as such, they know what "Memory Usage" ("Working Set" on Vista) really
means or what

They just see a number in Task Manager, and that our software is near the
top. We then get phone calls, emails, forum posts, and whatnot all saying
"how could your software take 80 megs? I've only got 512, and your app is
the biggest thing running on the machine!". Now we've got an unhappy
customer.
Why do they "get cranky" then?

We're taking up too much memory, according to the list they're seeing (In
Task Manager). On many systems, we're at or near the top - taking up nearly
as much memory as Outlook. Even a tiny "Hello World" WinForms .Net program
exhibits this behavior.
If they don't know exactly what these counters are about, why are they
looking at them and why do they "get cranky" then?

They're uneducated users looking at Task Manager. By "uneducated", I mean
even most experienced developers.

We've had a number of customer evaluate using our stuff (and .Net) and then
choosing not to use it, because all the .Net apps they build take up too
much memory. They're very worried about the negative perception this will
cause, and end up building native Win32 apps.
But again, this is not the real issue, you are forcing your users to run
as full admins (a big NO NO per default on Vista) which makes them
vulnerable to all sort of security attacks, this is what I call *reality*,
tell them about this and let them make an educated choice.

It's not woth trying to educating the users. There are too many of them, and
it's a losing battle. It's also an expensive battle, as it takes alot of
time & resources.

I would put the blame for this one on the CLR team - all .Net apps appear to
suck memory like they're beind the proverbial green door and the customer is
flashing cash. There's no reason for this, and it makes everyone who builds
apps using .Net look terrible.

Some guy builds a decent IM client in Delphi and it runs in like 2 megs of
memory. I build "hello world" and it takes 50 megs - by the time I'm feature
comparable to the Delphi app, I'm up to 80 or so megs of memory. For an IT
department trying to decide on a standard, the decision is often made based
on that. We can talk about working set, heap size, performance counters,
page faults and the like until the cows come home, but the answer is right
there in task manager in the "Mem Usage" column, and that's the end of
it.... :(
 
?

=?ISO-8859-1?Q?Arne_Vajh=F8j?=

I have a small C# program (about 400 lines of code) that is only 28kb
after compiled.

However when it runs (takes a whole 5 seconds) it takes up nearly 20MB
of memory and I don't see why.

Some of the assembly I used:

using System;
using System.Collections.Generic;
using System.Windows.Forms;
using System.Xml.Serialization;
using System.IO;
using System.Diagnostics;
using System.Management;

The program read (de-serialize) a XML file, then generate a list. Then
the program read through the event log and see if anything match the
list.

Is there anyway I can reduce the memory usage?

Probably not.

..NET runtime (as most modern environments) use some memory.

XML parsing is also known to use some memory.

Same for Win Forms.

Arne
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top