none
Why .NET does not reuse/compact free object in my case (memory leak issue) RRS feed

  • Question

  • I have a memory leak problem with my .NET 3.5 multi-threaded application run on Window server 2008. I found the process consumed 1 GB memory after few days running and still increasing. This is what I've tried to address the issue :


    - The Gen2 Heap Size is increasing non-stop over time while Gen0&Gen1 stay remain.

    - The large object heap size stay stable in about 1 MB, which are some objects that I have allocated for life-time of the application (those objects are a few dictionary with specified capacity)

    - !EEHeap shown that the app allocate more and more memory segment in Gen2 :

    Total LoaderHeap size: 0x79000(495616)bytes
    =======================================
    Number of GC Heaps: 1
    generation 0 starts at 0x1a3bddd0
    generation 1 starts at 0x1a375490
    generation 2 starts at 0x025a1000
    ephemeral segment allocation context: none
     segment    begin allocated     size
    025a0000 025a1000  0359f9bc 0x00ffe9bc(16771516)
    0bd80000 0bd81000  0c87a5b0 0x00af95b0(11507120)
    0dba0000 0dba1000  0e56a2f0 0x009c92f0(10261232)
    0f190000 0f191000  0fc9cfd0 0x00b0bfd0(11583440)
    10190000 10191000  10998720 0x00807720(8419104)
    11190000 11191000  11c380d0 0x00aa70d0(11170000)
    12190000 12191000  1295bbf4 0x007cabf4(8170484)
    13190000 13191000  13d0e578 0x00b7d578(12047736)
    15190000 15191000  158d9534 0x00748534(7636276)
    16190000 16191000  16d04c64 0x00b73c64(12008548)
    14190000 14191000  14d46794 0x00bb5794(12277652)
    17190000 17191000  17d06198 0x00b75198(12013976)
    18d60000 18d61000  19942f84 0x00be1f84(12459908)
    19d60000 19d61000  1a7dd73c 0x00a7c73c(10995516)
    Large object heap starts at 0x035a1000
     segment    begin allocated     size
    035a0000 035a1000  036c1aa8 0x00120aa8(1182376)
    Total Size  0x97297b4(158504884)
    ------------------------------
    GC Heap Size  0x97297b4(158504884)

    - !dumpheap -stat shown that a lot of Free object is increasing over time but the application somehow does not reuse these free memory and allocate more memory overtime:

    7207da1c     6825       682500 System.Net.Sockets.OverlappedAsyncResult
    70ec88c0    92655      4471548 System.String
    70ecb330    12959     10870420 System.Byte[]
    004aefc0    17221    133162956      Free

    - I have tried to do a GC.Collect() to force an immediate garbage collection of all generation but these huge Free object still stay there.

    - Look at these free object with dumpheap -Type Free . The size of these free object is various but i found a lot of contiguous large size which can be reusable :

    11af63f4 004aefc0   179468 Free
    11b221f4 004aefc0    57212 Free
    11b30284 004aefc0    55508 Free
    11b3e030 004aefc0    40144 Free
    11b47e14 004aefc0    33512 Free
    11b505d0 004aefc0   260464 Free
    11b9001c 004aefc0    67484 Free
    11ba0bf8 004aefc0   619492 Free
    12191000 004aefc0   598516 Free
    122232f8 004aefc0   166308 Free
    1224c0dc 004aefc0   172144 Free
    12276240 004aefc0   288408 Free
    122bcd18 004aefc0   212100 Free
    122f0a78 004aefc0    84348 Free
    12305834 004aefc0    70120 Free
    12316ef0 004aefc0   112980 Free
    12332c84 004aefc0   413500 Free
    12398044 004aefc0   192380 Free
    123c70ac 004aefc0    62256 Free
    123d64f0 004aefc0    62172 Free
    123e58e0 004aefc0   109028 Free
    12400798 004aefc0    79084 Free
    12414108 004aefc0   100440 Free

    ...

    - As I might think the software need to allocate some larger object that does not fit those free memory. So i do a !dumpheap -Type String/System.Byte[] -min 50000 to find large allocated object but i found no one.

    Why does .NET not compact/reuse these Free object and how to fix this memory leak issue? Thank you all a lot!






    • Edited by vuadapass Sunday, February 5, 2017 9:11 AM
    Sunday, February 5, 2017 5:09 AM

All replies

  •  Hi vuadapass,

    A memory leak can occur in a .NET  Framework application when you use  unmanaged code as part of the  application. This unmanaged code can  leak memory, and the .NET Framework  runtime cannot address that problem.

    Additionally, a project may only  appear to have a memory leak. This  condition can occur if many large  objects (such as DataTable objects)  are declared and then added to a  collection (such as a DataSet). The  resources that these objects own may  never be released, and the resources  are left alive for the whole run of  the program. This appears to be a  leak, but actually it is just a  symptom of the way that memory is  being allocated in the program.

    For more details, you can refer to https://support.microsoft.com/en-us/help/318263/how-to-identify-memory-leaks-in-the-common-language-runtime from MS com.

    For dealing with this type of issue,. Remember to call Dispose() on all IDisposable objects. Use the using statement.

    Best regards,

    Kristin


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    Monday, February 6, 2017 6:03 AM
  • Hi Kristin Xie,

    Thank you so much for your reply,

    I've carefully wrapped all IDisposable objects in Using/End using statement and I haven't found somewhere in my project that store large object but does not release, as I've checked using WinDbg/DebugDiag 2 to see if these kind of objects existing.

    Now i found an information on the article you mentioned:

    In a dynamically managed memory environment: The garbage collector can collect and free the memory but never returns it to the operating system. This occurs when the garbage collector cannot move the objects that are still in use to one portion of the memory and free the rest.

    It's look likely my case , isn't it? (I have a huge Free object but .NET never returns it to operating system). I think I should look deeply into this detail and need to find someway to fix my issue. Do you have any article describe more about this case?

    I have found a link at the final of the article but ironically it is dead : 317297 Roadmap for debugging hangs, memory leaks, deadlocks, and race conditions in Visual Basic .NET  .

    Monday, February 6, 2017 4:10 PM
  • This is normally due to pinned objects. You have a lot of 6825      System.Net.Sockets.OverlappedAsyncResult objects around which are normally pinned for the duration of the socket operation. If you have many not completely/wrong closed socket connections running you will get into trouble with memory fragmentation.

    You can inspect WCF and socket states with Netext extension which is much easier to use.

    https://netext.codeplex.com/

    Try

    !wsocket

    command to find out if a specific connection makes problems to get some hints which code might be having issues.


    Monday, February 6, 2017 10:06 PM
  • Hi Alois,

    Thank you very much for your reply ! I will try and come back later.

    Tuesday, February 7, 2017 3:31 AM
  • Hi Alois,

    Thank you very much for your reply ! I will try and come back later.

    @vuadapass

    What's the problem now? Have you tried Alois's suggestion?


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    Wednesday, February 8, 2017 5:51 AM
  • Note that in both links information concerning buffers is mentioned. Second link advises sleeping thread for 1 millisecond helps too.

    With dot net sockets and overlapped I/O you see a spike in memory in your application

    Memory leak with socket BeginReceive?


    La vida loca

    • Proposed as answer by Kristin Xie Friday, February 17, 2017 2:44 AM
    Wednesday, February 8, 2017 6:10 AM