How to Force Disposal of Objects / GC

11,374

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();

Share:
11,374
anonymous1110
Author by

anonymous1110

Updated on June 04, 2022

Comments

  • anonymous1110
    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
    anonymous1110 almost 12 years
    tblCashExpenses = null; then il add GC.COllect() 2x? on my try block?
  • anonymous1110
    anonymous1110 almost 12 years
    Hi, how can i dispose the datacontext? i have a separate class on my business layer. ill add it in a while..
  • keyboardP
    keyboardP almost 12 years
    You can simply call the datacontext.Dispose method - msdn.microsoft.com/en-us/library/…
  • anonymous1110
    anonymous1110 almost 12 years
    hi, i have added my business layer class. Kindly take a look at it thanks.
  • Sergey Kalinichenko
    Sergey Kalinichenko almost 12 years
    @anonymous1110 Yes, see if this helps.
  • anonymous1110
    anonymous1110 almost 12 years
    would this work? public void submit() { CashExpensesDB.SubmitChanges(); CashExpensesDB.Dispose(); }
  • keyboardP
    keyboardP almost 12 years
    You 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 call Dispose for you once the end of the block is reached. See if that helps fix the error.
  • anonymous1110
    anonymous1110 almost 12 years
    hi, 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
    keyboardP almost 12 years
    Move 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 the submit bit). Now try saving it. Yes, you can comment out the first line.
  • keyboardP
    keyboardP almost 12 years
    You're welcome :) See if it fixes your saving issue and the memory problem, otehrwise something else is causing the memory exception.
  • Ferdinand Brunauer
    Ferdinand Brunauer almost 6 years
    This 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..