How to Force Disposal of Objects / GC
Solution 1
You should dispose your DataContext
. I can't see it being removed anywhere, so the connection will remain open and references may be held on to (preventing the GC from picking them up). This may be what's causing the problem. If you don't want to dispose manually, you can perform the transaction within a using
block.
Edit in response to Business Layer update -
You can wrap the methods in using
blocks like this:
public void insert(CashExpense item)
{
using(CEADataStoreDataContext CashExpensesDB = new CEADataStoreDataContext())
{
CashExpensesDB.CashExpenses.InsertOnSubmit(item);
CashExpensesDB.SubmitChanges();
}
}
Solution 2
Assign nulls to variables referencing your objects, the use GC.Collect();
to force garbage collection. You may need to call it twice in a row to speed non-accessible objects through the process.
Solution 3
Set the object to null, then call:
GC.Collect(); GC.WaitForPendingFinalizers();
anonymous1110
Updated on June 04, 2022Comments
-
anonymous1110 over 1 year
How do you force objects to dispose after use in order to free up memory? And, how do you force GC to collect?
Here's my Save Code. I've noticed that, every time I execute this function, my memory consumption goes up that would eventually caused an out of memory error after a couple of hits.
protected void btnSaveEmptyOC_Click(object sender, EventArgs e) { try { if (ViewState["ServiceDetailID"].ToString() != null) { CashExpense tblCashExpenses = new CashExpense(); Guid CashExpensesID = Guid.NewGuid(); tblCashExpenses.CashExpensesID = CashExpensesID; tblCashExpenses.ServiceDetailsID = new Guid(ViewState["ServiceDetailID"].ToString()); tblCashExpenses.Description = txtDescriptionEmptyOC.Text; tblCashExpenses.Quantity = Decimal.Parse(txtQTYEmptyOC.Text); tblCashExpenses.UnitCost = Decimal.Parse(txtUnitCostEmptyOC.Text); tblCashExpenses.CreatedBy = User.Identity.Name; tblCashExpenses.DateCreated = DateTime.Now; tblCashExpenses.CashExpensesTypeID = "OTHER"; CashExpenses_worker.insert(tblCashExpenses); CashExpenses_worker.submit(); //Clear items after saving txtDescriptionEmptyOC.Text = ""; txtQTYEmptyOC.Text = ""; txtUnitCostEmptyOC.Text = ""; ValidationMessage.ShowValidationMessage(MessageCenter.CashExpenseMaintenace.InsertOC2, "SaveEmptyOC", this.Page); MyAuditProvider.Insert(this.GetType().ToString(), ViewState["MarginAnalysisID"].ToString(), MessageCenter.Mode.ADD, MessageCenter.CashExpenseMaintenace.InsertOC2, Page.Request, User); divOtherCost.Visible = false; grd_othercost.Visible = true; btnaddothercost.Visible = true; tblCashExpenses = null; } else { ValidationMessage.ShowValidationMessage(MessageCenter.CashExpenseMaintenace.SaveServiceDetailOC, "SaveEmptyOC", this.Page); } } catch { ValidationMessage.ShowValidationMessage(MessageCenter.CashExpenseMaintenace.InsertOCError, "SaveEmptyOC", this.Page); } finally { //Rebinds the Grid populategrd_othercost(); Dispose(); GC.SuppressFinalize(this); } }
Here's My business layer class
public class CashExpensesBL { CEADataStoreDataContext CashExpensesDB = new CEADataStoreDataContext(); public IEnumerable<CashExpense> get() { return CashExpensesDB.CashExpenses; } public IEnumerable<CashExpense> get(Expression<Func<CashExpense, Boolean>> express) { return CashExpensesDB.CashExpenses.Where(express); } public void insert(CashExpense item) { CashExpensesDB.CashExpenses.InsertOnSubmit(item); } public void delete(CashExpense item) { CashExpensesDB.CashExpenses.DeleteOnSubmit(item); } public void deleteDC(Guid servicedetailid) { CashExpensesDB.sp_deleteDefaultCost(servicedetailid); } public void submit() { CashExpensesDB.SubmitChanges(); } }
-
anonymous1110 almost 12 yearstblCashExpenses = null; then il add GC.COllect() 2x? on my try block?
-
anonymous1110 almost 12 yearsHi, how can i dispose the datacontext? i have a separate class on my business layer. ill add it in a while..
-
keyboardP almost 12 yearsYou can simply call the
datacontext.Dispose
method - msdn.microsoft.com/en-us/library/… -
anonymous1110 almost 12 yearshi, i have added my business layer class. Kindly take a look at it thanks.
-
Sergey Kalinichenko almost 12 years@anonymous1110 Yes, see if this helps.
-
anonymous1110 almost 12 yearswould this work? public void submit() { CashExpensesDB.SubmitChanges(); CashExpensesDB.Dispose(); }
-
keyboardP almost 12 yearsYou can update your other methods like above. Basically, you're opening the DataContext only when you need it, and closing it as soon as you don't need it.
Using
blocks will automatically callDispose
for you once the end of the block is reached. See if that helps fix the error. -
anonymous1110 almost 12 yearshi, should I remove the CEADataStoreDataContext CashExpensesDB = new CEADataStoreDataContext(); on my first line? in my business layer? I tried adding using{} on the submit and insert, it caused my save button to not work.it is as if the new data wasnt save.
-
keyboardP almost 12 yearsMove the
SubmiteChanges()
code into the actual method like I've done in my answer. This way, it runs with the same DataContext (before, the DataContext was removed before it got to thesubmit
bit). Now try saving it. Yes, you can comment out the first line. -
keyboardP almost 12 yearsYou're welcome :) See if it fixes your saving issue and the memory problem, otehrwise something else is causing the memory exception.
-
Ferdinand Brunauer almost 6 yearsThis will not work, because a single GC.Collect() call just moves the object to the next generation. There is no way, to gurantee that that GC.Collect() even does something..