How to free the unused occupied memory?
Page 1 of 114 Replies - 683 Views - Last Post: 24 February 2013 - 05:54 PM
#1
How to free the unused occupied memory?
Posted 06 February 2013 - 12:05 PM
So how can I free up the unused memory? Thanks in advance.
Replies To: How to free the unused occupied memory?
#2
Re: How to free the unused occupied memory?
Posted 06 February 2013 - 12:11 PM
The garbage collector will free the memory when it needs to. Unless your program is using up a load of system resources don't worry about it. The only thing you can really do is make sure you don't sustain any references to un-needed objects. If you still have a reference then the garbage collector won't free it. That being said still don't get caught up in it. Let the garbage collector do its job.
#3
Re: How to free the unused occupied memory?
Posted 06 February 2013 - 12:15 PM
The long and sort of that means that your memory is going up because you are continuing to create objects that are remaining in scope (remaining alive).
So the fix for that is not GC - but fixing the logic of your program. I know that's not what you wanted to hear but that's how the cookie crumbles.
#4
Re: How to free the unused occupied memory?
Posted 06 February 2013 - 04:49 PM
Read up on what IDisposable.Dispose actually does, as well as what GC.Collect does. You'll see that they don't fix memory issues in your program.
Now, as to finding the actual leaks in your program, I have no real experience. I'm sure there are some profilers that could help; I've never used them. I'd be interested in hearing other experts' advice about this as well.
#5
Re: How to free the unused occupied memory?
Posted 06 February 2013 - 06:55 PM
http://msdn.microsof...chapt05_topic10
I wish I could find the other page because it had some nice illustrations of how memory is allocated and freed by different coding patterns. To me the illustrations spoke more to me about the impact of how I write my code as compared to the bulleted list in the link above.
#6
Re: How to free the unused occupied memory?
Posted 07 February 2013 - 05:38 AM
The long and sort of that means that your memory is going up because you are continuing to create objects that are remaining in scope (remaining alive).Then when I don't need these objects anymore how to tell the garbage collector that they aren't being used anymore and are to be destroyed? I suspect not telling it might be the reason.
Here's the code I'm currently using:
public class Page
{
public DockContainer dock; public TabPage tab; public Form1 owner; public Shape oblik;
public int ind; bool started;
//irrelevant code....
public Page(Form1 f)
{
//some irrelevant code, namely initialziing variables
dock = new Crom.Controls.Docking.DockContainer();
//some lines of code setting the initial properties of dock
tab = new System.Windows.Forms.TabPage();
//some lines of code setting the initial properties of tab
tab.Controls.Add(dock);
owner.TabControl1.Controls.Add(tab);
}
public void Dispose()
{
oblik.Dispose(true, owner);
dock.Dispose();
tab.Dispose();
GC.Collect();
}
//more irrelevant code...
}
//another class - owner is an instance of Page
// I call this when I want to close the tabpage
private void closeButton_Click(object sender, EventArgs e)
{
owner.Dispose();
}
Using this code upon pressing the close button the current TabPage is closed and this is due to tab.Dispose(); - when I remove tab.Dispose(); the tabpage is not closed, so I thought tab.Dispose(); is also calling destructors and stuff, which delete all the objects belonging to the tab page, but apparently it isn't. How do I do that? I suppose that the tabpage is still kept in the memory even though it's not shown in the tabcontrol anymore.
Should I finalize the variables or set them to null or both or what?
#7
Re: How to free the unused occupied memory?
Posted 07 February 2013 - 06:28 AM
http://msdn.microsof...e/bb985010.aspx
As I understand things, the point here is that the NextObjectPtr keeps moving up. (I'm not privy to the actual implementation, but I suspect it can be moved back down is some very special cases as optimization.) Conceptually, though, think of the NextObjectPtr keeps moving up until it hits the limit, and garbage collection happens. When that happens, the current segment is garbage collected, compacted, and promoted a generation. So that means that memory segment isn't freed up, but will be used later for other generations of objects that get promoted. A new segment is allocated to be used to satisfy the new set allocations. When the NextObjectPtr hits the end of the new segment another garbage collection happens again and objects are promoted again. Another segment is allocated again. The repeats until you have 3 generations: gen 0, gen 1, and gen 2.
More details here: http://msdn.microsof...he_managed_heap
So although you posted your code above, you still didn't fully disclose your calling pattern. When you say that memory usage keeps on going up, has your program already reached a steady state where you've been running and using it for awhile, and it still continues to eat memory?
I'm very leery about your way of closing a TabPage. Did you remove it first from the TabControl's Controls collection prior to disposing the TabPage? You have to recall that some of the WinForms controls that first appeared in .NET 1.1 are very thin wrappers around the Win32 controls and there is an implicit assumption that developers would continue to use them in the calling pattern as if some was writing a Win32 program rather than the newer style offered by WPF.
Also: You seem to be using a 3rd party control as the DockContainer. Are you sure it's not leaking (unmanaged) GDI resources?
In the end, we are all speculating here. Your best bet is to invest time (and possibly money) into getting a profiler that actually shows your memory usage patterns and you'll be better able to address your memory concerns, or lay your concerns to rest if things are working as designed.
#8
Re: How to free the unused occupied memory?
Posted 07 February 2013 - 12:58 PM
#9
Re: How to free the unused occupied memory?
Posted 08 February 2013 - 02:20 PM
triangulator, on 07 February 2013 - 08:38 AM, said:
The long and sort of that means that your memory is going up because you are continuing to create objects that are remaining in scope (remaining alive).Then when I don't need these objects anymore how to tell the garbage collector that they aren't being used anymore and are to be destroyed? I suspect not telling it might be the reason.
Using this code upon pressing the close button the current TabPage is closed and this is due to tab.Dispose(); - when I remove tab.Dispose(); the tabpage is not closed, so I thought tab.Dispose(); is also calling destructors and stuff, which delete all the objects belonging to the tab page, but apparently it isn't. How do I do that? I suppose that the tabpage is still kept in the memory even though it's not shown in the tabcontrol anymore.
Should I finalize the variables or set them to null or both or what?
You don't need to manually tell the GC to collect. You can, but it's frowned upon. The GC will collect when it gets ready to. There is no schedule. If you are removing all references and handling everything correctly in your Dispose, then the objects are getting disposed of correctly. However, the memory won't be reclaimed until the GC collects. That could be 2 minutes from the time you call Dispose, or 2 hours, or longer.
Don't worry about the size of the memory your application is using until you notice a problem like an OutOfMemoryException is thrown. Your app will consume a lot of memory. That memory will be reclaimed eventually if you are killing all of the references correctly.
As Adam states, one of the main "memory leaks" that occurs in .Net is when we do not unsubscribe from events. Anytime you manually do a "+=" to subscribe, you also need to unsubscribe("-="). Without the unsubscription, the object will remain in memory as it will still have a reference for the event handler.
#10
Re: How to free the unused occupied memory?
Posted 10 February 2013 - 01:42 AM
void dosomething(ref Point a, ref Point B)/>
{
Point temp = new Point();
//does some geometric calculations with the three points;
a.X = temp.X;
b.Y = temp.Y;//now I don't need temp anymore
temp = null;//my question is - is this line even necessary?
}
As far as I understood, it is necessary since it tells the GC to destroy temp and/or to free the memory it is using, otherwise it remains until the program ends. Is this so?
#11
Re: How to free the unused occupied memory?
Posted 10 February 2013 - 02:24 AM
So, assuming temp does reference an object allocated on the managed heap...
No, setting temp to null is not necessary. As soon as dosomething() returns, the object that was referenced by temp will become unreachable anyway, and so will be automatically eligible for garbage collection. Further, you must remember that setting a field to null won't cause the garbage collector to run.
One case you may hear for setting a instance field to null (often in a Dispose() method) is when that field references a very large object. What that will do is ensure that the large object can be garbage collected promptly (if necessary), even if the containing object is still referenced by the calling code. The argument is that that may help to significantly reduce memory pressure, due to the size of the object.
I think that's really defensive though, and if you've called Dispose() on the containing object, should it really still be in scope in your code? Setting large object fields to null may be a reasonable precaution in a public API that is going to be used by many developers, in many different ways, but in well written code that is not going to be used publicly, it's probably of little value, in my opinion.
So, I would say there is usually, in a well written application, absolutely no need to set references to null just for the sake of the garbage collector. Besides, I personally think it is a good idea to aim to avoid nulls in production code all together.
In summary, scope objects sensibly (for example, don't have a load of unnecessary static variables), and the garbage collector will do its job well; freeing you from any memory related worries. As tlhIn`toq suggested, if you find yourself having to set variables to null to allow memory to be reclaimed, you have a problem in the way your application is structured.
This post has been edited by CodingSup3rnatur@l-360: 10 February 2013 - 06:12 AM
Reason for edit:: Note about Point being a struct, not a class.
#12
Re: How to free the unused occupied memory?
Posted 10 February 2013 - 02:48 AM
Quote
Destructors (or, more precisely, finalizers), and Dispose() are NOT in the business of freeing managed memory. They are used for freeing resources that the garbage collector cannot clean up, like file handles, db connections etc.
Remember that finalizers simply define pieces of code that run before an object is finally garbage collected, in order to clean up unmanaged resources. If an object that defines a finalizer is never made eligible for garbage collection, then the finalizer will never run.
I don't know if you have a C++ background (the evidence suggests you may have), but C++ destructors are very different to C# finalizers. Don't let the similar syntax fool you
owner.TabControl1.Controls.Add(tab);
If owner remains reachable after the tab page is closed, the tab page won't be eligible for garbage collection because the tab control's Controls collection still holds a reference to the tab page. Maybe try removing the tab pages from the Controls collection, as well as disposing of them?
I believe the call to Dispose() on the tab page should indirectly remove it from the Controls collection, but that is assuming you actually call Dispose() on all the Page instances you create...
If that is causing a problem, the problem with likely transitively apply to this code too - tab.Controls.Add(dock);, meaning each DockContainer you create will not become eligible for garbage collection.
Our new junior developer at work made that mistake, where they were constantly adding controls to the Controls collection, without ever removing them, and consequently getting out of memory exceptions days after starting the application up.
EDIT: I've just noticed you are actually calling owner.Dispose(), and that Skydiver already made the above point. My apologies, guess I haven't fully woken up yet... Anyway, assuming owner.Dispose() is always called when the page is closed, that should mean all controls on the Form1 instance are removed from their Controls collections (as I believe Dispose() does this for you), meaning the above probably doesn't apply in this case.
Just a side note, accessing a form's UI control directly from the outside like that is bad practice. The form itself is the only one who should be able to add or remove controls directly like that.
This post has been edited by CodingSup3rnatur@l-360: 10 February 2013 - 06:38 AM
#13
Re: How to free the unused occupied memory?
Posted 10 February 2013 - 06:32 AM
#14
Re: How to free the unused occupied memory?
Posted 24 February 2013 - 12:42 PM
Here is the code I have currently:
public class Page
{
public DockContainer dock; public TabPage tab; public Form1 owner; public Shape myshape;
public int ind; bool started,dispozd=false;
System.EventHandler<Crom.Controls.Docking.FormEventArgs> bzbg;
System.EventHandler bzbgtab;
public Page(Form1 f, string _ss, int kk)
{
started = true;
//.....
bzbg = new System.EventHandler<Crom.Controls.Docking.FormEventArgs>(this.dockContainer1_FormClosed);
dock.FormClosed += bzbg;
//....
bzbgtab = new System.EventHandler(this.initialize);
tab.Enter += bzbgtab;
// ....
tab.Controls.Add(dock);
owner.shapes.Controls.Add(tab);
//....
}
public void Dispose()
{
if (!dispozd)
{
dispozd = true;
owner.broi--;
owner.shapes.Controls.Remove(tab);
dock.FormClosed -= bzbg;
tab.Enter -= bzbgtab;
tab.Controls.Remove(dock);
MessageBox.Show("im being disposed "+tab.Text);
myshape.Dispose(true, owner);
dock.Clear();
dock.Dispose(); dock.Hide();
tab.Controls.Clear();
tab.Dispose(); tab.Hide();
dock = null; tab = null; myshape = null;
}
}
//...
I get all the messages, remove the controls from the containers, remove the references, dispose all childs and yet all controls - including the instances of class Page above and the tab pages - remain, although not in the tabcontrol. Now I'm probably going to ask a stupid question, but how do I delete those objects? There is no function such as .Close() or .Delete() or .End() or .Stop() or whatever. I am certainly missing something big here.
Also, I don't do anything with the GC manually anymore.
#15
Re: How to free the unused occupied memory?
Posted 24 February 2013 - 05:54 PM
|
|

New Topic/Question
Reply



MultiQuote







|