I was tracking a problem of memory leak related to an event handler,while I've discovered that each time I open a raddoCking then I close it I got around 500kb of memory used and not released.
I'm using MVVM pattern and as far I've seen its not related to the mvvm library.
When I close a RadPane I set it context to null hasn't it enough?
Thanks
You need to call RadPane's RemoveFromParent() method for it to be garbage collected.
Please check out these links:
http://www.telerik.com/forums/radpanegroup-memory-leak
http://www.telerik.com/forums/radpane-not-garbage-collected-when-closed
Few Points:
Setting RadPane's context to null isn't enough. You should unsubscribe from any event subscription to any long lasting objects and call Dispose for all disposable objects.
How do you measure memory? It would not release memory right after you close the RadPane. Garbage collection occurs only when it is required. If you want to test memory usage you should call GC collect and finalization before that.
GC.Collect();
GC.WaitForPendingFinalizers();
However, if you want to track memory leaks accurately, you need to use a proper profiling tool which would show you growing objects and their retention graphs.
Have a look at this answer for a good memory profiler.
Related
I have windows form application in this I used Infragistics controls. I analyze the memory process after opening the form memory usage goes 27 MB but after closing it memory should release but it not working. While closing I called Dispose method also.
Some thoughts.
Don't use Task Manager to diagnose memory problems. Use a memory profiler. .Net manages its memory in a way which is not entirely obvious and Task Manager gives false assumptions about that nature of this.
Just because you dispose something, it doesn't mean the garbage collector is going to race to clean up and aggressively give memory back to the operating system, it will do it when it feels like it based on memory pressure and heuristics .
If you create a form (and its modal) you might as well just put it in a using statement, then you have peace-of-mind that you are doing everything correctly
Additional Resources
Fundamentals of Garbage Collection
I have a custom application that allows to open some custom models.
If I open a model in the application, then open another model - memory isn't released from the first model.
When I try to profile memory leak with profiler (ANTS memory profiler), the application releases memory and I'm not able to track the leak. How can I manage this problem?
When you take a snap shot ANTS memory profiler does a full garbage collection.
When you want to take a snapshot, I normally take 2-3 snapshots until there is not memory differences between two consecutive snapshots. Then compare with your base snapshot.
Go to instance list and see if there is any instances are growing. Select the Objects with Source in order to get rid of heaps of system object.
If there is any growing instances, pick one and see the objects retention graph which will show you exactly which instance holds the reference.
And also, make sure that you have implemented IDisposable properly and dispose all disposable objects and unsubscribe from all event subscriptions.
Have a look at below walkthroughs
http://www.red-gate.com/products/dotnet-development/ants-memory-profiler/walkthrough http://www.red-gate.com/products/dotnet-development/ants-memory-profiler/
I'm writing a game in C# with SharpDX...
So, for drawing a frame, currently i'm using a Timer, with interval set to 1;
But this is too slow for a game, so i want something faster...
First of all, if I use another thread for the game (and another for the Window itself) and i use a "[while (InGame)]" statement, it is fast, but the GC will never release a single object, and the memory usage just going up and up...
IF I use the SharpDX built in "RenderLoop" function, it is fast also, but the GC still doesn't do anything...
I've tried to override the Window form "WndProc" function, but the game only refresh itself then i'm moving the mouse like a crazy men...
This is my first real game, with a lot of functions,
so if any of you have any idea, how would i fix it, or what should I use, I would appreciate it...
There must be something in the Window Form lifecycle like a
void FormLife
{
WndProc();
HandleEvents();
etc...
}
(It was just a hard example...)
OR how can i force the GC to do its job, at the end of the while(InGame) state ?
I've tried GC.Collect(); but its dont work...
Don't put your game logic in the UI classes.
Use a multimedia timer and a dispatcher to return to main thread for rendering. From my experience a cycle of 5mSec works well. (Lower will waste CPU time).
Use dispatcher priority of Input so that the timer won't choke the UI and prevent it handling user events.
On timer event, if the previous update hasn't completed, return immediately without doing anything (you can use System.Threading.Interlocked.CompareAndExchange as a cheap sync method).
To make game run faster, try to reuse objects and change their states or to pass short living immutables so that the GC won't delay your program.
Use the IDisposable pattern where applicable.
If GC.Collect does not free memory you have a memory leak. Use the memory profiling tool of your choice to spot the leak (PerfView, Windbg, .NET Memory Profiler, YourKit, ....)
Besides this the best allocation is no allocation at all. If you reuse objects and keep unused objects in a pool you can get rid of GCs almost entirely. Even if you stay away from Gen 2 collections which can block your game for hundreds of ms you also need to keep a sharp eye on Gen 0/1 collections which can also cause noticeable delays.
See http://social.msdn.microsoft.com/Forums/vstudio/en-US/74631e98-fd8b-4098-8306-8d1031e912a4/gc-still-pauses-whole-app-under-sustainedlowlatency-latencymode-despite-it-consumes-025gb-and?forum=clr
You don't typically have to worry about memory management. If you are making sure not to hold on to references then the garbage collector should do its thing automatically based on memory pressure.
You can force it yourself using GC.Collect but you need to be absolutely certain you really need to. Most of the time its not required. Check this thread for more info and points to consider: Best Practice for Forcing Garbage Collection in C#
Since the objects are not being collected you must be holding a reference to them somewhere.
You didn't post much code so it is hard to say where you are holding a reference.
In the past I've used windbg to find the root cause of of memory issues. VS2013 has a memory profiler built in (might be easier to use).
A common case I've seen of holding references is via event subscription. If you have subscribed to any events you have to make sure you unsubscribe to release the object. see Why and How to avoid Event Handler memory leaks? for more details. That doesn't look like your problem.
I am working on a relatively large solution in Visual Studio 2010. It has various projects, one of them being an XNA Game-project, and another one being an ASP.NET MVC 2-project.
With both projects I am facing the same issue: After starting them in debug mode, memory usage keeps rising. They start at 40 and 100MB memory usage respectively, but both climb to 1.5GB relatively quickly (10 and 30 minutes respectively). After that it would sometimes drop back down to close to the initial usage, and other times it would just throw OutOfMemoryExceptions.
Of course this would indicate severe memory leaks, so that is where I initially tried to spot the problem. After searching for leaks unsuccesfully, I tried calling GC.Collect() regularly (about once per 10 seconds). After introducing this "hack", memory usage stayed at 45 and 120MB respectively for 24 hours (until I stopped testing).
.NET's garbage collection is supposed to be "very good", but I can't help suspecting that it just doesn't do its job. I have used CLR Profiler in an attempt to troubleshoot the issue, and it showed that the XNA project seemed to have saved a lot of byte arrays I was indeed using, but to which the references should already be deleted, and therefore collected by the garbage collector.
Again, when I call GC.Collect() regularly, the memory usage issues seem to have gone. Does anyone know what could be causing this high memory usage? Is it possibly related to running in Debug mode?
After searching for leaks unsuccesfully
Try harder =)
Memory leaks in a managed language can be tricky to track down. I have had good experiences with the Redgate ANTS Memory Profiler. It's not free, but they give you a 14 day, full-featured trial. It has a nice UI and shows you where you memory is allocated and why these objects are being kept in memory.
As Alex says, event handlers are a very common source of memory leaks in a .NET app. Consider this:
public static class SomeStaticClass
{
public event EventHandler SomeEvent;
}
private class Foo
{
public Foo()
{
SomeStaticClass.SomeEvent += MyHandler;
}
private void MyHandler( object sender, EventArgs ) { /* whatever */ }
}
I used a static class to make the problem as obvious as possible here. Let's say that, during the life of your application, many Foo objects are created. Each Foo subscribes to the SomeEvent event of the static class.
The Foo objects may fall out of scope at one time or another, but the static class maintains a reference to each one via the event handler delegate. Thus, they are kept alive indefinitely. In this case, the event handler simply needs to be "unhooked".
...the XNA project seemed to have saved a lot of byte arrays I was indeed using...
You may be running into fragmentation in the LOH. If you are allocating large objects very frequently they may be causing the problem. The total size of these objects may be much smaller than the total memory allocated to the runtime, but due to fragmentation there is a lot of unused memory allocated to your application.
The profiler I linked to above will tell you if this is a problem. If it is, you will likely be able to track it down to an object leak somewhere. I just fixed a problem in my app showing the same behavior and it was due to a MemoryStream not releasing its internal byte[] even after calling Dispose() on it. Wrapping the stream in a dummy stream and nulling it out fixed the problem.
Also, stating the obvious, make sure to Dispose() of your objects that implement IDisposable. There may be native resources lying around. Again, a good profiler will catch this.
My suggestion; it's not the GC, the problem is in your app. Use a profiler, get your app in a high memory consumption state, take a memory snapshot and start analyzing.
First and foremost, the GC works, and works well. There's no bug in it that you have just discovered.
Now that we've gotten that out of the way, some thoughts:
Are you using too many threads?
Remember that GC is non deterministic; it'll run whenever it thinks it needs to run (even if you call GC.Collect().
Are you sure all your references are going out of scope?
What are you loading into memory in the first place? Large images? Large text files?
Your profiler should tell you what's using so much memory. Start cutting at the biggest culprits as much as you can.
Also, calling GC.Collect() every X seconds is a bad idea and will unlikely solve your real problem.
Analyzing memory issues in .NET is not a trivial task and you definitely should read several good articles and try different tools to achieve the result. I end up with the following article after investigations: http://www.alexatnet.com/content/net-memory-management-and-garbage-collector You can also try to read some of Jeffrey Richter's articles, like this one: http://msdn.microsoft.com/en-us/magazine/bb985010.aspx
From my experience, there are two most common reasons for Out-Of-Memory issue:
Event handlers - they may hold the object even when no other objects referencing it. So ideally you need to unsubscribe event handlers to destroy the object automatically.
Finalizer thread is blocked by some other thread in STA mode. For example, when STA thread does a lot of work the other threads are stopped and the objects that are in the finalization queue cannot be destroyed.
Edit: Added link to Large Object Heap fragmentation.
Edit: Since it looks like it is a problem with allocating and throwing away the Textures, can you use Texture2D.SetData to reuse the large byte[]s?
First, you need to figure out whether it is managed or unmanaged memory that is leaking.
Use perfmon to see what happens to your process '.net memory# Bytes in all Heaps' and Process\Private Bytes. Compare the numbers and the memory rises. If the rise in Private bytes outpaces the rise in heap memory, then it's unmanaged memory growth.
Unmanaged memory growth would point to objects that are not being disposed (but eventually collected when their finalizer executes).
If it's managed memory growth, then we'll need to see which generation/LOH (there are also performance counters for each generation of heap bytes).
If it's Large Object Heap bytes, you'll want to reconsider the use and throwing away of large byte arrays. Perhaps the byte arrays can be re-used instead of discarded. Also, consider allocating large byte arrays that are powers of 2. This way, when disposed, you'll leave a large "hole" in the large object heap that can be filled by another object of the same size.
A final concern is pinned memory, but I don't have any advice for you on this because I haven't ever messed with it.
I would also add that if you are doing any file access, make sure that you are closing and/or disposing of any Readers or Writers. You should have a matching 1-1 between opening any file and closing it.
Also, I usually use the using clause for resources, like a Sql Connection:
using (var connection = new SqlConnection())
{
// Do sql connection work in here.
}
Are you implementing IDisposable on any objects and possibly doing something custom that is causing any issues? I would double check all of your IDisposable code.
The GC doesn't take into account the unmanaged heap. If you are creating lots of objects that are merely wrappers in C# to larger unmanaged memory then your memory is being devoured but the GC can't make rational decisions based on this as it only see the managed heap.
You end up in a situation where the GC collector doesn't think you are short of memory because most of the things on your gen 1 heap are 8 byte references where in actual fact they are like icebergs at sea. Most of the memory is below!
You can make use of these GC calls:
System::GC::AddMemoryPressure(sizeOfField);
System::GC::RemoveMemoryPressure(sizeOfField);
These methods allow the garbage collector to see the unmanaged memory (if you provide it the right figures)
In my application, I have a lot of RichTextBoxes that are created dynamically in run time. I realized that the application has a memory leak, which is caused by the RichTextBox controls. To prove that the memory leaks because of the control I wrote the following test method:
for (int i = 0; i < 3000; i++)
{
Control rich = new RichTextBox();
pnl.Content = rich;
}
GC.Collect();
GC.WaitForPendingFinalizers();
pnl is a ContentControl that is declared in Xaml code.
If you run the following code, you can see that the memory usage is growing rapidly.
Any ideas how to solve the problem?
I considered creating an object pool, but this would complicate my application, and I rather avoid it.
edit: I've added call to the garbage collector to demonstrate that the objects are not garbage collected - there is no improvement in the memory usage with and without the call to the GC collect method.
Note that calling rich.Dispose within the loop eliminates the memory usage growth.
This isn't an indication that your application has a memory leak, it's an indication that your application is using a lot of memory. It's a leak if the RichTextBox controls don't get released at some point after they've fallen out of scope (detecting memory leaks on managed objects is notoriously difficult and unprovable).
A common misconception that an object falling out of scope will cause it to be garbage collected. This just makes it eligible to be collected. The object may theoretically never be collected until the application terminates. The fact that it grows with RichTextBox and not with other controls is not an indication that there is a memory leak in the RichTextBox, it's just an indication that it uses more memory per instance than other controls. While this information may be useful, it doesn't help when determining whether or not there's a memory leak.
Found this elsewhere, and it seems to be correct as far as my testing is concerned.
When a FlowDocument is created,
relatively expensive formatting
context objects are also created for
it in its StructuralCache. When you
create multiple FlowDocs in a tight
loop, a StructuralCache is created for
each FlowDoc. Let's you called
Gc.Collect at the end of the loop,
hoping to recover some memory.
StructuralCache has a finalizer
releases this formatting context, but
not immediately. The finalizer
effectively schedules an operation to
release contexts at
DispatcherPriority.Background.
So the RichTextBox (or FlowDocument) in case is not leaking just waiting on a background thread to cleanup. When it runs exactly who knows. I wish this just implemented a dispose method that would force a cleanup immediately.
We had the same problem in winforms 2.0 and we had to buy a 3rd party rich text control. I guess that Microsoft didn't bother to fix it...
This fixed the issue to me:
http://blingcode.blogspot.com/2010/10/memory-leak-with-wpfs-richtextbox.html
Basically add two attributes to each RichTextBox :) :)
IsUndoEnabled="False"
Regarding your edit:
You've added the GC calls after the loop terminates and all 3000 RichTextBoxes have been created.
While I agree that it seems odd that the previous one isn't freed inside the loop when it's replaced by a new one, it's such a tight loop that the GC probably isn't getting a chance to "do it's stuff" before the loop terminates.
I don't think it's a good idea (but it should be OK in test code), but have you tried moving the GC calls inside the loop?