locked
EF, SaveChanges: How to release memory after adding object to entity? RRS feed

  • Question

  • Hello!

    I have to save data into database every 100 milliseconds. I managed this by creating a connection (context) in a new thread.
    I calculate data and call AddToXXXX method. After that I execute SaveChanges method with SaveOption set to AcceptAllChangesAfterSave.
    Btw: My thread is active 24/7. It just saves data.

    Everything seems to work fine (let's put aside the performance, I should SaveChanges every n-th iteration).
    I can see data in database with manager.

    The problem is the my program is taking all memory available after few hours (1GB RAM). Then the process is slowed down (and all other processes).
    After watching what is going on in the debugger I think all my added objects are kept in memory.

    Do you have any suggestions?

    I am using VS2010 + SQL Server 2008 R2  (the production SQL Server version is 2005)

     

    Thanks

    Sunday, May 29, 2011 8:04 PM

Answers

  • If you just need to put data into a single entity it might be best to use a stored procedure instead. Then the EF context will have nothing to store. You can import or add the stored procedure into the edmx and let the template generate a method in the context so it's not hard to call.

     

    Another option might be to unattach the entities you've created in each iteration from the context ... then the context should not keep a reference to them (and to its own copy of the data needed for change tracking) and you should not be loosing memory. I believe. Something like

    while (true) {

       var entity = new BlahBlahBlah {...};

       context.AddToBlahBlahBlahs(entity);

       context.SaveChanges();

       context.BlahBlahBlahs.Detach(entity);

       wait_a_little();

    }

    • Proposed as answer by Patrice ScribeMVP Monday, May 30, 2011 8:26 AM
    • Marked as answer by [Beer] Monday, May 30, 2011 10:21 AM
    Monday, May 30, 2011 6:49 AM

All replies

  • Hi,

    Looks correct. The usual pattern is to add new objects to an entityset held by the context and all those objects are kept after changes are saved. You could :
    - dispose the old context and create a new context every nth addition
    -  or you could try to remove the added entity once it has been saved or clear this collection periodically

     


    Please always mark whatever response solved your issue so that the thread is properly marked as "Answered".
    Sunday, May 29, 2011 8:25 PM
  • Hi,

    thanks for a very quick answer.

    Yes. My first idea was disposing the context. But the problem is that it takes more than 1 second (according to my quick tests) to
    re-create the context --> So I might loose some data.

    It seems I'll need to re-design my approach (make some buffer and then store data from the buffer or something like that)

    I also find the idea of clearing the collection periodically very interesting. Do you have any code examples or. more precise directions.

    Thanks a lot

    Sunday, May 29, 2011 8:40 PM
  • If you just need to put data into a single entity it might be best to use a stored procedure instead. Then the EF context will have nothing to store. You can import or add the stored procedure into the edmx and let the template generate a method in the context so it's not hard to call.

     

    Another option might be to unattach the entities you've created in each iteration from the context ... then the context should not keep a reference to them (and to its own copy of the data needed for change tracking) and you should not be loosing memory. I believe. Something like

    while (true) {

       var entity = new BlahBlahBlah {...};

       context.AddToBlahBlahBlahs(entity);

       context.SaveChanges();

       context.BlahBlahBlahs.Detach(entity);

       wait_a_little();

    }

    • Proposed as answer by Patrice ScribeMVP Monday, May 30, 2011 8:26 AM
    • Marked as answer by [Beer] Monday, May 30, 2011 10:21 AM
    Monday, May 30, 2011 6:49 AM
  • Thanks JendaPerl and Patrice.

    I managed to solve the problem.
    Detaching object was the solution.

    Thanks again.


    Monday, May 30, 2011 10:24 AM