Forcefully Releasing memory

T

trialproduct2004

Hi all

I am having application in c# where i am loading one table of database
into dataset.
My table is of large size. so whenever i am loading that into dataset
my memory size is getting increased.

So what i want is as soon as i am setting dataset to null, memory
should be released.
But when i am looking into task manager for memory useage what i am
getting is same memory is till occupied by my application.

Can some one tell me how to forcefully release memory.

Please help me as this is very important for me.
Thanks in advance.
 
P

Pete Davis

Call GC.Collect().

That forces the garbage collector to collect the memory.

Pete
 
T

trialproduct2004

Hi

I tried with calling Gc.collect. But still memory usage in task manager
remains same.

I don't know why this is happening.

If you know reason behind this, please tell me.

thanks.
 
M

MuZZy

Pete said:
Call GC.Collect().
That forces the garbage collector to collect the memory.

Well, calling GC.Collect just asks GC to "please collect as soon as possible" which can be minutes...

Unfortunately all this dancing around GC doesn't help in many cases. We had a weird problem with
dramatically increasing memory thought we were releasing all datasets and arrays and profiler was
saying it's ok, so we finally came up with a solution:
Calling this function will "shake" your avail memory which does really help - you going to see an
immidiate used memory drop.

bool bTipAction = true;

public static void SetWorkingSet()
{
//Needs Admin rights on the machine

try
{
System.Diagnostics.Process loProcess = System.Diagnostics.Process.GetCurrentProcess();
if(m_bTipAction == true)
{
loProcess.MaxWorkingSet = (IntPtr)((int)loProcess.MaxWorkingSet - 1);
loProcess.MinWorkingSet = (IntPtr)((int)loProcess.MinWorkingSet - 1);
}
else
{
loProcess.MaxWorkingSet = (IntPtr)((int)loProcess.MaxWorkingSet + 1);
loProcess.MinWorkingSet = (IntPtr)((int)loProcess.MinWorkingSet + 1);
}
m_bTipAction = !m_bTipAction;
}
catch(System.Exception)
{
}
}


Good luck,
Andrey
 
P

Patrick

Here's some Remarks from MSDN:

Use this method to attempt to reclaim all memory that is inaccessible.
However, the Collect method does not guarantee that all inaccessible memory
is reclaimed.

All objects, regardless of how long they have been in memory, are considered
for collection; however, objects that are referenced in managed code are not
collected. Use this method to force the system to attempt to reclaim the
maximum amount of available memory.

Somewhat Ambiguous....
 
T

trialproduct2004

hi

thanks for your reply.

but i am not getting this function.

It is like instead of calling co.collect, i have t call setworkingset
function.

if you can explain this little bit, then it will easier for me to use
it in my code.

thanks.
 
W

Willy Denoyette [MVP]

See inline

Willy.

MuZZy said:
Well, calling GC.Collect just asks GC to "please collect as soon as
possible" which can be minutes...

NO, this is not true, calling GC.Collect is honoured as soon as the GC is
able to kick in, that is when managed code is at a GC safe point, I hope
your code doesn't spend minutes to reach a safe point :).
Unfortunately all this dancing around GC doesn't help in many cases. We
had a weird problem with dramatically increasing memory thought we were
releasing all datasets and arrays and profiler was saying it's ok, so we
finally came up with a solution:
Calling this function will "shake" your avail memory which does really
help - you going to see an immidiate used memory drop.

This is not a solution, because there is no problem, "dramatic increase" of
memory means what in terms of free memory? Does your application or other
applications running in the system suffer from a lack of memory?
If the answer to this question is NO, well, don't call GC.Collect or don't
trim the Working Set of your application.
If the answer is yes, run a memory profiler and look at your memory
allocation patterns, take a close look at your containers like Datasets,
Arraylists etc..., they are so easy to use but he! they come at a price and
they are largely overused, the result is that .NET applications are known to
be memory hungry. Right, .NET makes it possible to build windows
applications real fast, but to build well designed and well performing (in
terms of performance and resource consumption) is just as hard as any other
development platfom, with one exception, the time you win during development
can now be spent for designing and testing etc....

bool bTipAction = true;

public static void SetWorkingSet()
{
//Needs Admin rights on the machine

try
{
System.Diagnostics.Process loProcess =
System.Diagnostics.Process.GetCurrentProcess();
if(m_bTipAction == true)
{
loProcess.MaxWorkingSet = (IntPtr)((int)loProcess.MaxWorkingSet - 1);
loProcess.MinWorkingSet = (IntPtr)((int)loProcess.MinWorkingSet - 1);
}
else
{
loProcess.MaxWorkingSet = (IntPtr)((int)loProcess.MaxWorkingSet + 1);
loProcess.MinWorkingSet = (IntPtr)((int)loProcess.MinWorkingSet + 1);
}
m_bTipAction = !m_bTipAction;
}
catch(System.Exception)
{
}
}

What you are doing is realy bad, just like calling GC.Collect without having
any serious reason, reducing the working set is just as bad (well actually
worse). Don't fool yourself in thinking that your application uses less
memory because you reduced the WS, all you did is throw away (valuable?)
pages from memory (to the paging file). The result is that you disturb the
OS memory manager and pager, also you are inducing a lot of hard page faults
whenever a paged file has to be brought back into the working set. Worse you
disturb the GC even more when doing this, think what happens if pages from
the managed heap are paged-out, when the GC runs it has to reaload all the
pages from the paging file to perform a scan.
Funny that people are so paranoid about memory consumption these days, while
they don't seem to understand (or measure) the impact on other resources
when trying to play fast and loose with things that are much better left to
the OS and the GC itself to be done.
 
C

Craig Scheets

To hopefully clear up what others have said, I'll give it to you .Net memory
management at a high-level.

..Net does a lot of memory management for you (unlike many previous unmanaged
languages). When an object falls out of scope or the dispose() object is
explicitly called, it's earmarked for deletion next time garbage collection
runs. This memory is not freed up immediately though (this is what you're
experiencing).

Garbage collection runs on an "intelligent" algorithm and unless you really
research, you're not really ever supposed to call GC.Collect() yourself
because it breaks it's learning mechanism. I go ahead and do like you do
though, and I have used it a couple times after calling a HUGE memory
intensive operation that I won't ever need to do again any time soon. It
hasn't really caused any problems, so I don't worry about it.

IMPORTANT: GC.Collect() only frees up memory that's been earmarked to be
freed up though. If you're still in the same method/class/whatever where
the dataset (or whatever large object) is still in scope, NOTHING will free
up that memory until you explicitly call dispose() on the object or let it
go out of scope, and after one or the other then call GC.Collect().

Hope that helps,
Craig
 

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