So I have a program that increases the memory by 5MB per second. Since only 2GB can be allocated per application, I hit my limit at about 5 minutes after I start my program and get a System.OutOfMemoryException.
I have "done my homework" (hopefully good enough :D) and know that after the end of a block, the variables within that block are not disposed.
Ultimately, I need a way to automatically free the memory from variables used in after each block to stop the OutOfMemoryException from occurring.
P.S.: I realize there is a lot of confusion on this topic so if I made a mistake in my question, please feel free to correct me. But mostly, I would like to get this exception out of the way.
EDIT
Alright something weird happened. I copied the entire project from my desktop (where it doesn't work) to my laptop. And apparently, it works just fine on my laptop! The memory only increases MOSTLY by 500 KBps and is automatically freed 1 second later. I have no idea why, it's exactly the same project and no code was altered.
Anyone know why this happens?
Use these variables in a using statement and call GC.Collect() when done
In my experience, the most common way to leak memory in managed code is holding on to references for too long, alternatively not realizing how references are handled. A live reference will prevent garbage collection, no matter how well your code is disposing stuff.
Here is a decent article on how to figure out just what is leaking and where those references are, and you probably want to read up on the 'additional background' links as well.
Use ANTS profiler or CLRProfiler to determine which objects are taking up space and which methods are creating and holding references these object.
probably this discussion will help you to understand what is actually happening regarding memory management in .net Finalize/Dispose pattern in C#
and just in case, this is another post on how to dispose objects: the correct technique for releasing a socket/event/ummaged code with the dispose/finalize pattern
Maybe your objects should implement IDisposable so you can clean up resources when you no longer need them. This MSDN article shows how to implement it:
Digging into IDisposable
Related
We have application that runs 24h per day and 7 days per week. Sometimes CPU go to 100% and then go back to 80%. The same with RAM. Is it smart to manually call GC.Collect after few hours or betterto leave it automatically.
We are using C# 2010, SQL 2008 and Fluent Nhiberanet. This is desktop application.
I wouldn't call it smart to call GC.Collect() "every few hours", or "when RAM usage goes to high", but I'd call it smart to call it whenever you are in a position of having more information than the GC, some exmaples
You know, this big chunk of RAM or these many small objects you just allocated, will not be used again and you are in a singlethreaded environment and (ofcourse) you have cleared all your references
You know, that a "GC break" will hurt less right now, than a bit later
The GC is a highly optimized peace of code and quite smart, but it can only work on information it has.
Manually call the GC.Collect is never a good idea as you should investigate why your app is getting that much resources instead of clean them up every time you are about to reach 100%
Have a look at the below I think it really worth a read
Chapter 5 — Improving Managed Code Performance
normally the framework itself will handle calling the GC when it's needed
you could try to run it without calling it yourself for a day
GC.Collect won't magically solve problems if you hold unnecessary references or forget to unsubscribe from delegates. The framework collects garbage by itself from time to time, so I don't believe calling GC.Collect every few hours can change anything.
Short answer: no.
The garbage collector is not an area you want to be going into unless you have to. Normally the .net runtime does a pretty good job of calling it whenever it's needed. If you call it yourself it will just be additional overhead.
I would refrain from calling GC.Collect - exceptional cases as described here and here aside.
IF you have any application running 24/7 then I would recommend the following:
check real hard for memory leaks and correct any such leak (using multiple memory profilers)
IF you need any links please say so...
try your very best to reduce resource usage by optimizing/rewriting your code
configure the application to use GC in "server mode" as that is designed for 24/7 situations (for details see here)
This is not a miracle solution but something you should try with your application and compare whether it gives you any benefits.
I know all the theories :
I know what is GC, when to call dispose, Finalise when it is getting called.
I would like to know, in your live project ..in which scenario have used all this.
I mean when the project
manager/client insisted you to
cleanup the memory ? When you find
any errors in the programs? Kind of
error messages or error logs? When
your program got crashed because of
unwanted memory? or any other
scenarios?
You should not care when and how GC is called. It is inteligent enough to know when to run and what objects to free.
You should also Dispose, either manualy or using "using" all objects, that implement IDisposable. You will then prevent many errors with un-managed resources, like files.
And if you are running out of memory, then there is something wrong with your algorithm or code itself. Manualy calling GC.Collect is heavily discuraged, especialy in production code.
As a rule of thumb, you need to implement IDisposable if you aggregate a disposable object, or if you hold on to an unmanaged resource. Cleanup is done differently for these two scenarios. Otherwise, keep it simple, don't litter your code with dotnetisms
Similar question here
Memory leaks cause crashed up servers. Cause and effect.
Ressource management is something you just havce to do. It is not 'my client insisted I free my memory'. It is simply good practice. Not all applications may crash and the user just restarts them - there is one or other server application out there.
If you start building your programming libraries, ressource management and concurrency should be your top priority, otherwise you will never be up to speed implementing any solution.
hth
Mario
I have a windows service multithreaded application for indexing purpose which have six threads. It is working fine except memory leakage. Actually when the service is started, then the service is consuming 12,584kb memory, after some time it is taking memory of 61,584 kb. But after indexing process is complete it is not releasing memory.
I need it come back to its previous position after the indexing is complete, that is it should take the memory with which it started e.g. 12,584kb in this case.
I have used garbage collection but it is not doing what I want.
Can anyone please help me?
First advice would be to throw a memory profiler at it. I've always been happy with Red Gate's ANTS profiler, which will help identify which objects are leaking, if any.
Do bear in mind that there may be first time initialisation happening all over the place, so you probably want to track it over time
.NET doesn't release memory to satisfy people staring at Task Manager. Allocating memory is expensive. The CLR is designed to do so sparingly, and to hold onto any memory it allocates as long as possible. Think of it this way--what's the point of having 4gb of memory when you're not using half of it?
Unless you actually KNOW that you have a memory leak (as in, your app crashes after two days of uptime), let me give you a piece of advice... Close Task Manager. Don't optimize for memory before you know you need to. Relax, guy. Everything is fine.
61 MB does not sound out of the ordinary. You will need to let the service run for awhile and monitor its memory usage for a rising trend. If you see the application leveling out at a certain value then there is probably nothing to worry about.
I agree with Will completely - however I offer 2 small pieces of advice:
Don't use GC.Collect. Trust me you are not going to improve the CLR's Garbage Collection algorithm by doing this. In fact objects that are ready to be collected but can't be for some reason will be moved to Tier 2, where they will have to wait even longer before being collected (thereby potentially making any leak you may have worse!)
Check everywhere in your code that you have created some type of stream (usually MemoryStream) and verify that the streams are being closed properly (preferably in a "finally" block)
Here I am using "log4net-1.2.10" for handling exception, "Lucene.net-2.1.0.3" for indexing, here is one "IndexWriter" class for add document in index or delete documents from index.
lock (object)
{
indexWriter.AddDocument(document);// indexWriter object of "IndexWriter" class.
}.
Also we use microsoft message queue for retrieving messages.
I had the same problem until I changed the applcation from STA to MTA:
[MTAThread]
public static void Main()
instead of
[STAThread]
public static void Main()
(I've used Red Gate's ANTS profiler...)
My app was using 150mb of memory not to long ago, now it is at 286mb. It slowly rises so i must be forgetting to dispose something. This isnt much of a problem for me since i have 4gb but i want to send this to others who have only 1gb of ram. other then going through the code line by line how can i find objects that need to be disposed of or just generally large objects?
Extending both JP and Reed's answers.
I wanted to clear up a bit of confusion. If you are seeing significant increases in memory the issue is unlikely to be a problem with calling Dispose. Dispose is typically used to free up unmanaged resources like handles. These don't take up much memory but instead are more precious as resources.
Increases in memory are generally associated with large objects or collections being accessible from a managed object being rooted directly or indirectly via a stack object or a strong GC handle. This is the area you will likely want to focus your investigation on.
Check out the .NET Memory Profiler. There is a 15-day trial and it's well worth the license fee.
Easily identify memory leaks by
collecting and comparing snapshots of
.NET memory Snapshots include data
about the .NET instance allocations
and live instances at the time the
snapshot was collected. They provide a
lot of useful information and make it
easy to identify potential memory
leaks, especially when two snapshots
are compared.
heres a method i use:
http://www.codeproject.com/KB/dotnet/Memory_Leak_Detection.aspx
You can also use WinDbg and SOS. These have the advantage of being free and very, very thorough, if a bit tricky to get used to.
Here's a blog post describing the process.
Here are couple of tricks using the ANTS Memory Profiler to help find undisposed objects and fix the leaks.
The ANTS Memory profiler allows a filter to be set that show just
objects that contain a Dispose() method. Turn this on, and you'll be
given a list of live objects that have not been disposed.
While finding undisposed objects is useful, even more useful is
knowing why these objects are not being disposed. Finding where these
undisposed objects are created goes a long way to finding the
reason for the leak. If you are able to change the code of the leaking object, a
useful trick is to introduce a field to hold a stacktrace, and
populate this field at the time of object construction. Then because
the ANTS memory profiler allows you to inspect fields of objects,
you can simply read off the stacktrace as it was at the time the leaking objects were created. This will give you a strong clue as to who the
owner of the leaking objects should be, and how they should go about calling Dispose on the objects they are responsible for.
Code project currently has a link to an app specifically for finding undisposed objects.
http://www.codeproject.com/KB/dotnet/undisposed.aspx
Check out this link
Stephen Toub goes into great length to explain various techniques for doing this,
Following are some brief highlights from his article
By adding a finalizer for debugging purposes, you can introduce a way to find out when
a class was not properly disposed,if the finalizer is never invoked, you know that
disposed wasn't called
To get additional information about the instance, threadIds etc to aid in narrowing down
which instance didn't have it's disposed invoked, he creates a FinalizationDebgger class
which your disposable class would hold onto which wouldin turn call the Dispose of the
FinalizationDebugger class instance when it itself is disposed. If Dispose isn't called on
your class instance then when the Finalizer runs it will invoke the finalizer for
FinalizationDebgger instance where in you could assert or throw an exception to help debug
the problem,
Move all the tracking related code into a base class which your disposable class would
then inherit from, which makes the code much cleaner. This approach may or may not work
since your burn a base class and if you are inheriting from another base already.
In the last option everything is factored out into a static class that your instances
call into. The FinalizationDebugger becomes a static class that exposes three static
methods: Constructor, Dispose, and Finalizer. The idea is that you call these methods
from the appropriate place in your class(dispose/finalize/constructor).This is minimally
invasive into your code, as it typically involves adding only three lines of code. All
of these methods are marked with a ConditionalAttribute such that they'll only be called
by your class when you compile your class in DEBUG mode.
Stephen also explains the pros and cons of each of his approaches.
The solutions presents various options and you would need to evaluate each to figure out which one works best for your situation. A MUST read IMHO
Hope this helps.
Also try out ANTS Memory Profiler. There's a 14 day fully functional free trial, and I really like the UI.
Disclosure: They sponsor Herding Code right now, which is why I tried it out. But I'm really impressed with it - I profiled an application for 30 hours and got tons of useful information out of it. The UI is really helpful - it guides you through the process, and it looks dang purty.
alt text http://www.red-gate.com/products/ants_memory_profiler/images/object_retention_graph.gif
I wrote C++ for 10 years. I encountered memory problems, but they could be fixed with a reasonable amount of effort.
For the last couple of years I've been writing C#. I find I still get lots of memory problems. They're difficult to diagnose and fix due to the non-determinancy, and because the C# philosophy is that you shouldn't have to worry about such things when you very definitely do.
One particular problem I find is that I have to explicitly dispose and cleanup everything in code. If I don't, then the memory profilers don't really help because there is so much chaff floating about you can't find a leak within all the data they're trying to show you. I wonder if I've got the wrong idea, or if the tool I've got isn't the best.
What kind of strategies and tools are useful for tackling memory leaks in .NET?
I use Scitech's MemProfiler when I suspect a memory leak.
So far, I have found it to be very reliable and powerful. It has saved my bacon on at least one occasion.
The GC works very well in .NET IMO, but just like any other language or platform, if you write bad code, bad things happen.
Just for the forgetting-to-dispose problem, try the solution described in this blog post. Here's the essence:
public void Dispose ()
{
// Dispose logic here ...
// It's a bad error if someone forgets to call Dispose,
// so in Debug builds, we put a finalizer in to detect
// the error. If Dispose is called, we suppress the
// finalizer.
#if DEBUG
GC.SuppressFinalize(this);
#endif
}
#if DEBUG
~TimedLock()
{
// If this finalizer runs, someone somewhere failed to
// call Dispose, which means we've failed to leave
// a monitor!
System.Diagnostics.Debug.Fail("Undisposed lock");
}
#endif
We've used Ants Profiler Pro by Red Gate software in our project. It works really well for all .NET language-based applications.
We found that the .NET Garbage Collector is very "safe" in its cleaning up of in-memory objects (as it should be). It would keep objects around just because we might be using it sometime in the future. This meant we needed to be more careful about the number of objects that we inflated in memory. In the end, we converted all of our data objects over to an "inflate on-demand" (just before a field is requested) in order to reduce memory overhead and increase performance.
EDIT: Here's a further explanation of what I mean by "inflate on demand." In our object model of our database we use Properties of a parent object to expose the child object(s). For example if we had some record that referenced some other "detail" or "lookup" record on a one-to-one basis we would structure it like this:
class ParentObject
Private mRelatedObject as New CRelatedObject
public Readonly property RelatedObject() as CRelatedObject
get
mRelatedObject.getWithID(RelatedObjectID)
return mRelatedObject
end get
end property
End class
We found that the above system created some real memory and performance problems when there were a lot of records in memory. So we switched over to a system where objects were inflated only when they were requested, and database calls were done only when necessary:
class ParentObject
Private mRelatedObject as CRelatedObject
Public ReadOnly Property RelatedObject() as CRelatedObject
Get
If mRelatedObject is Nothing
mRelatedObject = New CRelatedObject
End If
If mRelatedObject.isEmptyObject
mRelatedObject.getWithID(RelatedObjectID)
End If
return mRelatedObject
end get
end Property
end class
This turned out to be much more efficient because objects were kept out of memory until they were needed (the Get method was accessed). It provided a very large performance boost in limiting database hits and a huge gain on memory space.
You still need to worry about memory when you are writing managed code unless your application is trivial. I will suggest two things: first, read CLR via C# because it will help you understand memory management in .NET. Second, learn to use a tool like CLRProfiler (Microsoft). This can give you an idea of what is causing your memory leak (e.g. you can take a look at your large object heap fragmentation)
Are you using unmanaged code? If you are not using unmanaged code, according to Microsoft, memory leaks in the traditional sense are not possible.
Memory used by an application may not be released however, so an application's memory allocation may grow throughout the life of the application.
From How to identify memory leaks in the common language runtime at Microsoft.com
A memory leak can occur in a .NET
Framework application when you use
unmanaged code as part of the
application. This unmanaged code can
leak memory, and the .NET Framework
runtime cannot address that problem.
Additionally, a project may only
appear to have a memory leak. This
condition can occur if many large
objects (such as DataTable objects)
are declared and then added to a
collection (such as a DataSet). The
resources that these objects own may
never be released, and the resources
are left alive for the whole run of
the program. This appears to be a
leak, but actually it is just a
symptom of the way that memory is
being allocated in the program.
For dealing with this type of issue, you can implement IDisposable. If you want to see some of the strategies for dealing with memory management, I would suggest searching for IDisposable, XNA, memory management as game developers need to have more predictable garbage collection and so must force the GC to do its thing.
One common mistake is to not remove event handlers that subscribe to an object. An event handler subscription will prevent an object from being recycled. Also, take a look at the using statement which allows you to create a limited scope for a resource's lifetime.
This blog has some really wonderful walkthroughs using windbg and other tools to track down memory leaks of all types. Excellent reading to develop your skills.
I just had a memory leak in a windows service, that I fixed.
First, I tried MemProfiler. I found it really hard to use and not at all user friendly.
Then, I used JustTrace which is easier to use and gives you more details about the objects that are not disposed correctly.
It allowed me to solve the memory leak really easily.
If the leaks you are observing are due to a runaway cache implementation, this is a scenario where you might want to consider the use of WeakReference. This could help to ensure that memory is released when necessary.
However, IMHO it would be better to consider a bespoke solution - only you really know how long you need to keep the objects around, so designing appropriate housekeeping code for your situation is usually the best approach.
I prefer dotmemory from Jetbrains
Big guns - Debugging Tools for Windows
This is an amazing collection of tools. You can analyze both managed and unmanaged heaps with it and you can do it offline. This was very handy for debugging one of our ASP.NET applications that kept recycling due to memory overuse. I only had to create a full memory dump of living process running on production server, all analysis was done offline in WinDbg. (It turned out some developer was overusing in-memory Session storage.)
"If broken it is..." blog has very useful articles on the subject.
After one of my fixes for managed application I had the same thing, like how to verify that my application will not have the same memory leak after my next change, so I've wrote something like Object Release Verification framework, please take a look on the NuGet package ObjectReleaseVerification. You can find a sample here https://github.com/outcoldman/OutcoldSolutions-ObjectReleaseVerification-Sample, and information about this sample http://outcoldman.com/en/blog/show/322
The best thing to keep in mind is to keep track of the references to your objects. It is very easy to end up with hanging references to objects that you don't care about anymore.
If you are not going to use something anymore, get rid of it.
Get used to using a cache provider with sliding expirations, so that if something isn't referenced for a desired time window it is dereferenced and cleaned up. But if it is being accessed a lot it will say in memory.
One of the best tools is using the Debugging Tools for Windows, and taking a memory dump of the process using adplus, then use windbg and the sos plugin to analyze the process memory, threads, and call stacks.
You can use this method for identifying problems on servers too, after installing the tools, share the directory, then connect to the share from the server using (net use) and either take a crash or hang dump of the process.
Then analyze offline.
From Visual Studio 2015 consider to use out of the box Memory Usage diagnostic tool to collect and analyze memory usage data.
The Memory Usage tool lets you take one or more snapshots of the managed and native memory heap to help understand the memory usage impact of object types.
one of the best tools I used its DotMemory.you can use this tool as an extension in VS.after run your app you can analyze every part of memory(by Object, NameSpace, etc) that your app use and take some snapshot of that, Compare it with other SnapShots.
DotMemory