Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Memory Leak / GC not cleaning up objects #20009

Open
jasonl1234 opened this issue Jun 22, 2020 · 3 comments
Open

Memory Leak / GC not cleaning up objects #20009

jasonl1234 opened this issue Jun 22, 2020 · 3 comments

Comments

@jasonl1234
Copy link

The attached zip has a sample program and 2 heap captures plus their console output, in case running the program poses a problem or a quick look that heap captures will be useful. I can re-run it with additional options as needed.

The sample program (inner zip) demonstrates a strange (corner?) case where the GC is not collecting a chain of de-referenced objects. The program uses a linked list and 2 threads where (1) generate entries the list and (2) pull them out. No work is actually being done - just setting up the list node and moving head/tail references through by way of the "next" reference. I refer to this as a corner case because if it was the normal activity then every program everywhere would be having problems and that's clearly not the case.

The sample is the product of analysis of high memory usage on systems using the .Net ThreadPool. Over long periods of time, we see many thousands of QueueSegment objects chained together in the same way and no amount of GC calls will free the objects. So there is an real case for this and not just "hey look what I found" :)

Steps to Reproduce

  1. Compile and run the attached application with this command line:
    mono --profile=log:heapshot=ondemand,output=output-%t.mlpd MonoMemLeak.exe

  2. It will create the linked-list, thread to pull items, main thread will push 10 items, and then give you some console options: H to run a heap capture, G to run the GC, R to stop the producer thread, Q to quit.

  3. I typically do Heap, Gc many times (5, 10, 100, ... doesn't matter), Heap again, and Quit.

  4. run mprof-report to view the heap capture file. You will see a line like this which shows the Node objects are not being released.

    bytes count avg
    160 10 16 MonoMemLeak.Node

Current Behavior

GC is not cleaning up de-referenced objects correctly.

Expected Behavior

GC should clean up de-referenced objects correctly :)

On which platforms did you notice this

[ ] MaxOS
[x] Linux (ARM imx6)
[ ] Windows

Version Used:
Mono 6.4 and 6.8

SampleProgramAndCaptures.zip

@jasonl1234
Copy link
Author

jasonl1234 commented Jun 22, 2020

Sorry - forgot to mention in the ZIP, the "fixed" captures in the ZIP I posted are the output after changing the consumer thread to null out the NEXT reference on a given node as it processes it. While this would fix a given case in an application, it doesn't help things like the ThreadPool in mscorlib which is having the same problem with it's QueueSegment linked list.

@BrzVlad
Copy link
Member

BrzVlad commented Jun 23, 2020

@jasonl1234 This is a known limitation in mono gc. Are the leaked object ConcurrentQueueSegment in your application ? If so this is a duplicate of #19665

@jasonl1234
Copy link
Author

@BrzVlad No we aren't using ConcurrentQueueSegment. In the main application we are using ThreadPool for deferred work, that uses QueueSegment, perhaps ConcurrentQueueSegment uses that too. In the test application I posted it's showing the problem with locally created classes and not using any of the .Net SDK objects mentioned.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants