.Net 4 MemoryCache Leaks with Concurrent Garbage Collection

前端 未结 4 552
刺人心
刺人心 2021-01-30 13:24

I\'m using the new MemoryCache in .Net 4, with a max cache size limit in MB (I\'ve tested it set between 10 and 200MB, on systems with between 1.75 and 8GB of memory). I don\'t

相关标签:
4条回答
  • 2021-01-30 13:57

    Stop-the-world garbage collection is based on determining whether a strong live reference to an object exists at the moment the world is stopped. Concurrent garbage collection usually determines whether a strong live reference to an object has existed since some particular time in the past. My conjecture would be that many strong references to objects held in WeakReferences are being individually created and discarded. If a stop-the-world garbage collector fires between the time a particular object is created and the time it's discarded, that particular object will be kept alive, but previously-discarded objects will not. By contrast, a concurrent garbage collector may not detect that all strong references an object have been discarded until a certain amount of time goes by without any strong references to that object being created.

    I've sometimes wished that .net would offer something between a strong reference and a weak one, which would prevent an object from being wiped from memory, but would not protect it from being finalized or having weak WeakReferences to it invalidated. Such references would slightly complicate the GC process, requiring every object to have separate flags indicating whether strong and quasi-weak references exist to it, and whether it has been scanned for both strong and quasi-weak references, but such a feature could be helpful in many "weak event" scenarios.

    0 讨论(0)
  • 2021-01-30 14:03

    MemoryCache definately has some issues. It ate 160Mb of memory on my asp.net server, just changed to simple list and added some extra logic to get the same functionality.

    0 讨论(0)
  • 2021-01-30 14:11

    You can "force" a garbage collection right after the problematic method and see if the problem reproduces executing:

    System.Threading.Thread.Sleep(200);
    GC.Collect();
    GC.WaitForPendingFinalizers();
    

    right at the end of the method (make sure that you free any handles to reference objects and null them out). If this prevents memory leakage, and then yes, there may be a runtime bug.

    0 讨论(0)
  • 2021-01-30 14:16

    I found this entry while searching for a similiar topic and I'm focusing on your Out of Memory exception.

    If you put an object in the cache then it still may be referencing other objects and therefore these objects would not be garbage collected -- hence the out of memory exception and probably a CPU being pegged out due to Gen 2 garbage collection.

    Are you putting "used" objects on the cache or clones of "used" objects on the cache? If you put a clone on the cache then the "used" object that possible references other objects could be garbage collected.

    If you shut off your caching mechanism does your program still run out of memory? If it doesn't run out of memory then that would prove that the objects you would otherwise be putting on the cache are still holding references to other objects hindering garbage collection.

    Forcing garbage collection is not a best practice and shouldn't have to be done. In this scenario forcing a garbage collection wouldn't dispose of referenced objects anyway.

    0 讨论(0)
提交回复
热议问题