.NET Framework Developer Center > .NET Development Forums > .NET Base Class Library > 580MB memory leaked from InternalTransaction[]
Ask a questionAsk a question
 

Question580MB memory leaked from InternalTransaction[]

  • Wednesday, November 04, 2009 6:58 AMQythyx Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     
    I'm not sure if this is the best forum for this question, if not please suggest another.

    We're running into a problem where over a number of days our service is leaking memory. Using MemProfiler (http://memprofiler.com) we've found that it is related to an increase in InternalTransaction[] objects. After about 5 days of running the service had 141,208 instances of these objects, which were using 580MB or RAM. Interestingly, very few InternalTransaction objects were in use, that is, it was the arrays that were the problem.

    Since this object is internal to the System.Transactions namespace there is no documentation on it, but it seems to be related to TransactionScope. We do use TransactionScope throughout our service, but we ALWAYS enclose it in a using statement, so it should not be leaking. Furthermore, MemProfiler agrees with this saying that no instances of TransactionScope exist.

    Another thought is that because we subscribe to the Transaction.TransactionCompleted event there could be a leak there. But, here too, MemProfiler shows no Transaction instances.

    I should mention that we are NOT using SqlServer. We're using PostgreSQL instead. Via some Postgres tools I managed to find that there were a few (6) long lasting, yet idle, Postgres processes. Postgres creates one process for each connection, but uses a pool to reuse them. I'm not a Postgres expert, but I thought it was odd that out of the 40 or so idle processes only a few were long lived, the rest were only a few seconds old. Anyway, using another Postgres tool I terminated these old processes and lo and behold the 141,000 InternalTransaction[] objects went away and freed up the 580MB or memory.

    What I really don't understand is how the thread that started these transactions could have finished, but left the InternalTransaction[] lying around. More importantly, what can I do to prevent this? As I said, I'm already disposing all of my transaction related objects.

    Possible related to this is how we're using the Transaction.TransactionCompleted event. There isn't a lot of documentation on this event. For example, what are the consequences of an exception being thrown from within our event handler?


    Any suggestions would be greatly appreciated.

All Replies

  • Wednesday, November 04, 2009 7:18 AMAldo John Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     
    I donno anything particular about Transactions. But if the memory is not reclaimed as you mentioned, you will have to check for any unintentional references to that memory. A very common mistake is event hooks (or delegates) which is not released (which will hold the object in memory till the event hook is realeased). Or any references to that using a static object.
  • Wednesday, November 04, 2009 10:24 AMJialiang Ge [MSFT]MSFT, ModeratorUsers MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     
    Hello

    I believe that it'll be very helpful if we can find out the SQL commands bound to those InternalTrascation objects. I introduced how to do it in my blog:
    http://www.cnblogs.com/Jialiang/archive/2009/06/10/1500921.html
    However, the article is in Chinese.

    I can try doing the analysis for you if you can share with me the memory dump of the leaking program. You can follow the article http://support.microsoft.com/default.aspx/kb/286350 or http://support.microsoft.com/kb/931673 to capture the dump file. After you get the dump, please let me know your email address by sending a mail to jialge@microsoft.com. Then I will create a file transfer workspace where you can upload your dump file. The dump will be kept confidential.
    Regards,
    Jialiang Ge
    MSDN Subscriber Support in Forum
    If you have any feedback of our support, please contact msdnmg@microsoft.com.
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.
    Welcome to the All-In-One Code Framework! If you have any feedback, please tell us.
  • Wednesday, November 04, 2009 11:57 AMQythyx Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     
    Aldo John, thanks for the suggestion. As far as I can tell the only possible connection we would have to the transaction related objects might be our attachment to the TransactionCompleted event, but from what I can tell that's not causing a problem.

    Jialiang Ge, thanks for the ideas. I'll try them as soon as I have a chance. It looks like enough of your Chinese article is command output, so I think I'll be able to piece together what you're suggesting. My one concern is that you describe this fro SqlConnections, but I'm dealing with PostgreSQL's NpgsqlConnections. I don't know if that will make a big difference.
  • Thursday, November 05, 2009 8:59 AMJialiang Ge [MSFT]MSFT, ModeratorUsers MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     
    Jialiang Ge, thanks for the ideas. I'll try them as soon as I have a chance. It looks like enough of your Chinese article is command output, so I think I'll be able to piece together what you're suggesting. My one concern is that you describe this fro SqlConnections, but I'm dealing with PostgreSQL's NpgsqlConnections. I don't know if that will make a big difference.

    Hello Qythyx

    I agree that this can be a big difference. I used .NET Reflector to study the internal structure of SqlConnection and assocate SqlConnections with transaction objects.
    Regards,
    Jialiang Ge
    MSDN Subscriber Support in Forum
    If you have any feedback of our support, please contact msdnmg@microsoft.com.
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.
    Welcome to the All-In-One Code Framework! If you have any feedback, please tell us.