Garbage Collection and Library Deployment

T

Trecius

Hello, Newsgroupians:

I've two, hopefully easy, questions.

First, I have a program that creates a relatively large array. The size is
in excess of 1,000,000 elements. Before my array is created, my RAM usage is
approximately 100 MB of 512 MB. When the array is finished being created and
populated, my RAM usage explodes to 475 MB. Because RAM is a valuable
resource for my low-end system, I call GC.Collect() and
GC.WaitForPendingFinalizers() AFTER CALLING MY METHOD, which the array is a
LOCAL variable to the method. However, looking at Task Manager, the RAM is
not released, and my application is still consuming approximately 350 MB of
RAM. Am I missing something?

Here's a sample of my code...

void MethodToCreateLargeArray()
{
object[] rgLargeArray;
// CREATE AND POPULATE rgLargeArray
}

void SomeMethod()
{
this.MethodToCreateLargeArray();
GC.Collect();
GC.WaitForPendingFinalizers();
}

That's it.


My second question has to do with building libraries. I have built a
library that I would like to distribute. When building the library, I ensure
the IDE is set to RELEASE. However, I've noticed that when I am using my own
library that I built in a separate project when my new application makes a
call to the library and the library has an exception, I can see all of my
code that I wrote for that library. How can I build my library that would
not allow people to see my code when the library throws an exception in debug
mode?


Thank you for your help.


Trecius
 
T

Trecius

Thank you, Mr. Duniho. You're response is most insightful.


Trecius

Peter Duniho said:
[...] Because RAM is a valuable
resource for my low-end system, I call GC.Collect() and
GC.WaitForPendingFinalizers() AFTER CALLING MY METHOD, which the array
is a
LOCAL variable to the method. However, looking at Task Manager, the RAM
is
not released, and my application is still consuming approximately 350 MB
of
RAM. Am I missing something?

Here's a sample of my code...

void MethodToCreateLargeArray()
{
object[] rgLargeArray;
// CREATE AND POPULATE rgLargeArray
}

void SomeMethod()
{
this.MethodToCreateLargeArray();
GC.Collect();
GC.WaitForPendingFinalizers();
}

That's it.

Well, you left out all the interesting parts, replacing them with a
comment.

But, most likely you're just seeing normal .NET behavior. Just because
you're done with the memory, that doesn't mean .NET releases the OS
allocation it made in order to satisfy your need. That would be
inefficient. Instead, it will continue to keep that allocation, in case
you wind up allocating another huge structure again.

In general, you should not call GC.Collect() or
GC.WaitForPendingFinalizers(). They are unnecessary, and usually will
have counter-intuitively detrimental effects on your program's
performance. For managing GC behavior, it's much more likely that you'd
use the Thread.BeginCriticalRegion()/EndCriticalRegion() methods, and even
that's a very rare need.

Just because RAM is "a valuable resource for your low-end system", that
doesn't mean your program should be explicitly trying to manage it. Let
..NET and Windows do their job, and focus on the stuff your program
actually has to do.
My second question has to do with building libraries. I have built a
library that I would like to distribute. When building the library, I
ensure
the IDE is set to RELEASE. However, I've noticed that when I am using
my own
library that I built in a separate project when my new application makes
a
call to the library and the library has an exception, I can see all of my
code that I wrote for that library. How can I build my library that
would
not allow people to see my code when the library throws an exception in
debug
mode?

That depends on what you mean by "see all of my code". From your
description, it sounds like you are looking at it in the debugger. If so,
then all you need to do to prevent others from seeing the code is to not
deliver a .pdb file and the source code along with your library.

Someone will still be able to use a tool like Red Gate's Reflector to
decompile the code, but that won't be a literal representation of your
actual code (e.g. no comments, variable names might be different,
implementation details that are provided by the compiler may appear, etc.)

Pete
 
G

Günter Prossliner

Hello
When playing with such a big arrays You can consider stackalloc
keyword which bypasses GC and gives You more control over memory
allocation.

Allocating even an Array of 1000000 Int32 is not managable on the Stack (as
it would be ~1MB and the stack size is 1 MB by default). When you do so, you
would need to set a higher stack-reserve / commit size. If it's a thread
stared by you, you may use the corresponding ctor argument, if it's the main
thread, you will have to modify the PE-Header (csc doesn't have an argument
for this).

I would advice against using the Stack for such things.


GP
 
C

Cor Ligthert[MVP]

Trecius,
However, looking at Task Manager, the RAM is
not released, and my application is still consuming approximately 350 MB
of
RAM. Am I missing something?
As thousand times is written in the .Net newsgroups, don't use the Task
Manager as tool for developing.

It is an enduser tool (there are possibilities to fake those as they give
you problems).

Willy has written a lot about this in the newsgroups, have a look too what
he wrote in the Net general newsgroup.

http://groups.google.com/group/micr...al&q=willy+taskmanager&qt_g=Search+this+group

Cor
 

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