Memory leaks in WPF/C# - c#

Please note this is done in WPF/C# and not in .net2.0 Winforms
I have a ListBox which contains objects of say Class X. Class X contains a BitmapSource object which is displayed in the listbox, so it displays similar to [Image] [Text]
This is loaded via the use of the CreateBitmapSourceFromHBitmap - note also that I call DeleteHBitmap to delete the handle of the HBitmap during this call, which is well known to do from posts I've seen on google/etc
I have a tree which contains said ListBox in each TreeViewItem - typically the tree has several items loaded. Users can drag/drop these images into different TreeViewItems. To handle these operation I manually call the operations:
<code>
ItemCollection.RemoveAt
</code>
<code>
ItemCollection.Insert
</code>
to move the images from the ListBox item collection, note when I insert I create a new Class X object to insert into the ListBox item collection
I have noticed I get a consistent memory leak from calling such operations several times, over the space of 5-10 mins of consistent dragging and dropping.
My question is:
Am I handling the moving of the BitmapSource's correctly? Is there something I'm doing to cause the Images to not be fully removed from the ItemCollection?
Or is there something fundamental I've missed?

Which is the definition of the variable that holds the image in you ClassX??? The problem may be in the fact that you are creating a new ClassX and the old one is no being deleted by the GC making the head have two different instance of ClassX.
Since you are using unmanged code (CreateBitmapSourceFromHBitmap) you should check if all the finalize method are correctly called (though close or dispose probably) and that the are no static references that can be pointing to your ClassX.
Remember that if you ClassX is not removed the Bitmap instance will be reachable in the graph made by the GC making it not to remove it from the heap.
I recommned using perfmon and add the .Net memory object to see if there are any object that survived finalize or pinned object, those are the one you are probably interested regarding the memory leak.
I hope it helps :P, but it will be nicer if you put the code of the ClassX.

Related

Preventing an object referenced by another form being destroyed upon child form termination

I have the following problem: An array of chart Series is passed from one form to another to be visualized in the child form i do this in order to enlarge the viewing area of a chart i have in my main window. It all works fine until i close the second form to which my Series have been passed at this point my application crushes an a null object reference is raised. Now I suspect my Series have been garbage collected upon that form termination. Any Ideas how this can be fixed and safely close that form without destroying the data?
Here is the code leading to the creation of the form.
Series[] tpSeries = { chart2.Series["S1"], chart2.Series["S2"] };
Dictionary<string, NumericUpDown> netParams = new Dictionary<string, NumericUpDown>()
{
{"N", numVertecies},
{"S", numS},
{"R", numR},
{"Gamma", numGama},
{"Beta", numBeta},
{"G", numG},
{"C0", numCzero},
};
TimePlotAnalysis tpForm = new TimePlotAnalysis(tpSeries, netParams); // N, s, r, gamma, beta, g, c_0
tpForm.Show();
Basically, your data should be in a separate class, then you simply share a class instance between forms.
There are many different ways to do this, depending on your particular use case. Here are a few examples:
How to share data between forms?
To Pass Values between two forms using C#
http://colinmackay.scot/2005/04/22/passing-values-between-forms-in-net/
Depending on your specific requirements, you might want to implement this object as a "singleton":
http://csharpindepth.com/Articles/General/Singleton.aspx
Now I suspect my Series have been garbage collected upon that form termination.
The issue has nothing in common with GC. You pass array of Series objects taken from a chart control in one form to another form, where (although you didn't show) I suspect you add them to another chart control.
Let take a look at Series class documentation.
Inheritance Hierarchy
System.Object
  System.Windows.Forms.DataVisualization.Charting.ChartElement
    System.Windows.Forms.DataVisualization.Charting.ChartNamedElement
      System.Windows.Forms.DataVisualization.Charting.DataPointCustomProperties
        System.Windows.Forms.DataVisualization.Charting.Series
Following the hierarchy, here is the base class definition
public abstract class ChartElement : IDisposable
Note the IDisposable? Now I guess you understand what is happening. When you close the second form, the Dispose method is called on the form and all the controls. The correct dispose implementations will in turn call dispose on any disposable object they hold (and we can assume MS controls do correctly implement the disposable pattern).
Shortly, I think the Series objects passed to the second form are disposed.
To fix the problem, as Reza Aghaei correctly pointed out in his comment, you should not pass Series objects to the second form, but the data that allows them to be recreated there. Or at least make sure you really create a new Series objects from the ones you pass.

Would setting a collection to null after assigning it to an itemssource clear up resources?

I was doing some performance optimization inside my app and there were a lot of places where I'm assigning a collection to the itemssource property of a listbox. When I assign the collection to the listbox is the original collection disposed from memory. If not, by setting it to null will it mark the collection for garbage collection?
For example:
void myWebServiceCompleted(object sender, List<Item> itemList)
{
ItemListBox.ItemsSource = itemList;
//Would setting itemList = null clear up resources?
}
I was just concerned because this type of assignment is made in multiple places in the app and if the above is true that means twice the memory.
No.
the ListBox holds a reference to your original list, so it is not garbage collected.
If for whatever reason you wanted the original list to get collected, you could manually add ListItems to the ListBox.
In this case the original list could get collected as long as there were no other references.
I guess this would be useful if each of the items in your collection was resource-heavy, and the listbox only needed to know a couple of fields (name and id for example)
No, it would not. itemList is a reference type. It's not duplicated like you think it is. Instead, you just have multiple references to it. It's like receiving multiple letters in the mail with the same address on them. It doesn't mean the house with that address is duplicated, just that there are multiple addresses referring to the same house.
As long as one rooted object still refers to your collection, it will not be freed by the garbage collector. Setting itemList to null has no effect on the total space consumed by this collection.
I was just concerned because this type of assignment is made in multiple places in the app and that means twice the memory.
It does not mean that. I strongly encourage you to drop everything you're doing and read about reference types until you understand this incredibly important point.
I now understand why Joel Spolsky thinks every programmer should learn C.

C#: Is there any way to easily find/update all references to an object?

I've been reading Rockford Lhotka's "Expert C# 2008 Business Objects", where there is such a thing as a data portal which nicely abstracts where the data comes from. When using the DataPortal.Update(this), which as you might guess persists 'this' to the database, an object is returned - the persisted 'this' with any changes the db made to it, eg. a timestamp.
Lhotka has written often and very casually, that you have to make sure to update all references to the old object to the new returned object. Makes sense, but is there an easy way to find all references to the old object and change them? Obviously the GC tracks references, is it possible to tap into that?
Cheers
There are profiling API's to do this but nothing for general consumption. One possible solution and one which I've used myself is to implement in a base class a tracking mechanism where each instance of the object adds a WeakReference to itself to a static collection.
I have this conditionally compiled for DEBUG builds but it probably wouldn't be a good idea to rely on this in a release build.
// simplified example
// do not use. performance would suck
abstract class MyCommonBaseClass {
static readonly List<WeakReference> instances = new List<WeakReference>();
protected MyCommonBaseClass() {
lock (instances) {
RemoveDeadOnes();
instances.Add(new WeakReference(this));
}
}
}
The GC doesn't actually track the references to the objects. Instead, it calculates which objects are reachable starting from global and stack objects at the runtime, and executing some variant of "flood fill" algorithm.
Specifically for your problem, why not just have a proxy holding reference to the "real" object? This way you need to update at only one place.
There isn't a simple way to do this directly, however, Son of Strike has this capability. It allows you to delve into all object references tracked by the CLR, and look at what objects are referencing any specific object, etc.
Here is a good tutorial for learning CLR debugging via SoS.
If you are passing object references around and those object references remain unchanged, then any changes made to the object in a persistence layer will be instantly visible to any other consumers of the object. However if your object is crossing a service boundary then the assemblies on each side of the object will be viewing different objects that are just carbon copies. Also if you have made clones of the object, or have created anonymous types that incorporate properties from the original object, then those will be tough to track down - and of course to the GC these are new objects that have no tie-in to the original object.
If you have some sort of key or ID in the object then this becomes easier. The key doesn't have to be a database ID, it can be a GUID that is new'ed up when the object is instantiated, and does not get changed for the entire lifecycle of the object (i.e. it is a property that has a getter but no setter) - as it is a property it will persist across service boundaries, so your object will still be identifiable. You can then use LINQ or even old-fashioned loops (icky!) to iterate through any collection that is likely to hold a copy of the updated object, and if one is found you can then merge the changes back in.
Having said this, i wouldn't think that you have too many copies floating around. IF you do then the places where these copies are should be very localized. Ensuring that your object implements INotifyPropertyChanged will also help propagate notifications of changes if you hold a list in one spot which is then bound to directly or indirectly in several other spots.

List.Add(this) inside of a class

I created a class awhile back. I used List.Add(this) inside of the class so I could access the controls I created later. It seemed to be very useful and I do not know how to create controls (more than one in the same parent control without a predefined limit) and access them later.
I was looking for Add(this) on the internet and couldn't find anymore information on it.
Is this a large resource hog or ineffective? Why can't I find more information on it? It seems very useful.
public class GlobalData
{
private static List<Member> _Members;
public partial class ChildrenPanel
{
private static List<ChildrenPanel> _ListCP = new List<ChildrenPanel>();
//X and Y position Panel | Container is the control recieving the Control
public void CreatePanel(int X, int Y, Panel Container)
{
//
// pnlStudent
//
_pnlStudent.BorderStyle = System.Windows.Forms.BorderStyle.Fixed3D;
_pnlStudent.Controls.Add(_lblCLastName);
_pnlStudent.Controls.Add(_lblCFirstName);
_pnlStudent.Controls.Add(_lblGrade);
_pnlStudent.Controls.Add(_lblSelected);
_pnlStudent.Controls.Add(_lblSeason);
_pnlStudent.Controls.Add(_lblAvailable);
_pnlStudent.Controls.Add(_lblGender);
_pnlStudent.Controls.Add(_ddlGrade);
_pnlStudent.Controls.Add(_ddlSelectedSports);
_pnlStudent.Controls.Add(_ddlAvailableSports);
_pnlStudent.Controls.Add(_ddlSeason);
_pnlStudent.Controls.Add(_rdbFemale);
_pnlStudent.Controls.Add(_rdbMale);
_pnlStudent.Controls.Add(_btnRemoveChild);
_pnlStudent.Controls.Add(_btnRemoveSport);
_pnlStudent.Controls.Add(_btnAddSport);
_pnlStudent.Controls.Add(_txtCLastName);
_pnlStudent.Controls.Add(_txtCFirstName);
_pnlStudent.Location = new System.Drawing.Point(X, Y);
_pnlStudent.Name = "pnlStudent";
_pnlStudent.Size = new System.Drawing.Size(494, 105);
//Still playing with the tab index
_pnlStudent.TabIndex = 10;
// Adds controls to selected forms panel
Container.Controls.Add(_pnlStudent);
// Creates a list of created panels inside the class
ListCP.Add(this);
}
Just make sure that you Remove the instance again when it's no longer needed, otherwise the List holding a reference to it will keep it in memory forever (Welcome to memory leaks in .NET after all).
I may revise this answer once I see some code, but my initial response is that it is not a resource hog. As to whether it is effective or not, some example code will be required.
Adding an object to a collection does not take up a large amount of resources because you are simply adding a reference to the object into the collection. You still only have a single object, but two (or more) variables that point to that object, so the only extra resources you are using are the minimal memory used by the references.
If your List is static or otherwise globally available, then you're doing something very bad.
ASP.Net is structured such that every request to your page - including postbacks - from every user results in a new instance of the page class. that's a lot of page instances. If references to all these instances are saved somewhere, the instances can never be garbage collected. You've created something analogous to a memory leak and you'll quickly find yourself running out of resources after you deploy to production.
The really dangerous thing here is that if you only do functional testing and no load testing the problem will likely not show up during your tests at all, because it will work fine for a few hundred (maybe even thousand) requests before blowing up on you.
If you're worried about dynamic controls, there are several better ways to handle this:
Put a fixed limit on the maximum number of controls you will allow, and add all of them to the page up front. Then only show/render them (toggled via the .Visible property) as you need them.
Make it data-driven. Rather than dynamically add a control, insert something to a database table and then bind a query on that table to a repeater or other data control (my preferred method).
Just make sure you're recreating every dynamic control you need at the right place (Pre-Init) in the page lifecycle.

how does linq2sql keep track of database objects?

When using Linq2sql everything automagically works. My experience is that going with the flow is not always the best solution and to understand how something internally works is better so you use the technique optimally.
So, my question is about linq2sql.
If I do a query and get some database objects, or I create a new one, somehow the linqcontext object keeps references to these objects. If something changes in one of the objects, the context object 'knows' what has changed and needs updating.
If my references to the object are set to null, does this mean that the context object also removes it's link to this object? Or is the context object slowly getting filled with tons of references, and keeping my database objects from garbage collecting?
If not, how does this work??
Also, is it not very slow for the database object to always go through the entire list to see what changed and to update it?
Any insight in how this works would be excellent!
thanks
yes, the context keeps references of the loaded objects. That's one of the reasons why it isn't meant to be used with a single instance shared accross the different requests.
It keeps lists for the inserts/deletes. I am not sure if it captures update adding those to a list, or it loops at the end. But, u shouldn't be loading large sets of data at a time, because that alone would be a bigger hit to performance than any last check it might do on the list.
The DataContext registers to your objects PropertyChanged event to know when it is modified. At this point it clones the original object and keeps it to compare the 2 objects together later when you do your SubmitChanges().
If my references to the object are set to null, does this mean that the context object also removes it's link to this object?
Edit: No. Sorry for my original answer I had misinterpreted what you had written. In that case the data context still has a reference to both object but will remove the relationship with those 2 objects on next SubmitChanges().
Be careful though. If you created your own objects instead of using the ones generated from the .dbml, the "magic" that the datacontext performs might not work properly.

Categories