本文介绍了.NET 4中的MemoryCache泄漏与并发垃圾回收的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用的是新的MemoryCache在.NET 4中,在MB A最大缓存大小限制(我测试过其设置在10至200MB,在系统的1.75和8GB的内存之间)。我没有设置任何基于时间的过期的对象,因为我使用的缓存仅仅作为一种高性能的驱动器,只要有空间,我希望它用。 让我吃惊的是,缓存拒绝驱逐任何对象,到如此地步,我会得到 SystemOutOfMemory 例外

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 set any time based expiration on the objects, as I'm using the cache simply as a high performance drive, and as long as there is space, I want it used. To my surprise, the cache refused to evict any objects, to the point that I would get SystemOutOfMemory exceptions.

我解雇了性能监视器,接线我的应用程序 .NET CLR内存\ #Bytes在所有堆 .NET内存缓存4.0 Process \ Private字节 - 事实上,内存消耗失控,并且没有缓存装饰都被注册

I fired up perfmon, wired up my application to .Net CLR Memory\#Bytes In All Heaps, .Net Memory Cache 4.0, and Process\Private Bytes -- indeed, the memory consumption was out of control, and no cache trims were being registered.

做了一些的谷歌上搜索 stackoverflowing 的,下载和连接的CLRProfiler,和的威猛的:驱逐无处不在!内存留根据内存大小限制我已经建立合理的范围内。在调试模式下跑了一遍,没有驱逐。 CLRProfiler再次驱逐。

Did some googling and stackoverflowing, downloaded and attached the CLRProfiler, and wham: evictions everywhere! The memory stayed within reasonable bounds based upon the memory size limit I had set. Ran it in debug mode again, no evictions. CLRProfiler again, evictions.

我终于发现,探查迫使应用程序,而不并发垃圾回收运行(也看到有用的SO并发垃圾回收问题)。我在我的app.config把它关掉了,和,果然,驱逐!

I finally noticed that the profiler forced the application to run without concurrent garbage collection (also see useful SO Concurrent Garbage Collection Question). I turned it off in my app.config, and, sure enough, evictions!

这似乎是最好的离谱缺少文件不说的:这个只适用于非并发垃圾回收的 - ,因为它移植从ASP.NET虽然我的形象,他们可能没有担心并发垃圾回收

This seems like at best an outrageous lack of documentation to not say: this only works with non-concurrent garbage collection -- .

所以有其他人看到了这一点?我很想得到一些其他方面的经验在那里,也许有些受过更多教育的见解。

So has anyone else seen this? I'd love to get some other experiences out there, and maybe some more educated insights.

更新1

我已经在一个单一的方法重现该问题:它似乎缓存必须写入并行高速缓存驱逐不火(在并发垃圾收集模式)。如果有一定的兴趣,我会上传测试code到公共回购。我肯定越来越走向的CLR / GC /的MemoryCache泳池的深水区,我想我忘了我的floaties ...

I've reproduced the issue within a single method: it seems that the cache must be written to in parallel for the cache evictions not to fire (in concurrent garbage collection mode). If there is some interest, I'll upload the test code to a public repo. I'm definitely getting toward the deep end of the the CLR/GC/MemoryCache pool, and I think I forgot my floaties...

更新2

我发表测试$在codePLEX C $ C到重现该问题。感兴趣的也可能,原有的生产code运行在Azure中,作为辅助角色。有趣的是,改变角色的app.config中的GC并发设置不起作用。可能Azure的覆盖很像ASP.NET GC设置?此外,运行WPF下的测试code VS一个控制台应用程序会产生稍有不同驱逐的结果。

I published test code on CodePlex to reproduce the issue. Also, possibly of interest, the original production code runs in Azure, as a Worker Role. Interesting, changing the GC concurrency setting in the role's app.config has no effect. Possibly Azure overrides GC settings much like ASP.NET? Further, running the test code under WPF vs a Console application will produce slightly different eviction results.

推荐答案

您可以迫使垃圾收集之后有问题的方法,看看问题是否重现执行:

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();

就在方法的末尾(确保你释放任何句柄引用的对象和空出来)。如果prevents内存泄漏,然后是的,有可能是一个运行时错误。

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.

这篇关于.NET 4中的MemoryCache泄漏与并发垃圾回收的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-20 02:42