当前位置: 首页 > 编程语言 > C#

如何测量.NETMemoryCache4.0的当前大小?分享

时间:2023-04-10 21:39:56 C#

如何衡量.NETMemoryCache4.0的当前大小?目前我们正在使用.NETMemoryCache4.0来满足缓存需求。(不是ASP.NET缓存,不是任何外部缓存)查看“.NETMemcache4.0”性能计数器,有关于缓存命中、未命中、条目、修剪等的数据,但没有关于大小的数据。有没有办法测量/了解生产应用程序使用的缓存的当前大小?我希望能够在不同的时间点捕获这些数据并获得缓存的平均大小。这是一个丑陋的实现细节,微软根本不想公开。在.NET中测量对象大小通常是不可能的。MemoryCache使用一个非常讨厌的后门来实现它的内存限制触发器,它使用了CLR的DACCESS组件,实际上是为了帮助实现内存分析器而设计的。你可以用调试器看到它??,所以它不是你无法到达它。您只需编写非常丑陋的代码来挖掘私有字段:usingSystem;使用System.Reflection;使用System.Runtime.Caching;公共静态类MemoryCacheHackExtensions{publicstaticlongGetApproximateSize(此MemoryCache缓存){varstatsField=typeof(MemoryCache).GetField(“_stats”,BindingFlags.NonPublic|BindingFlags.Instance);varstatsValue=statsField.GetValue(缓存);varmonitorField=statsValue.GetType().GetField("_cacheMemoryMonitor",BindingFlags.NonPublic|BindingFlags.Instance)varmonitorValue=monitorField.GetValue(statsValue);varsizeField=monitorValue.GetType().GetField("_sizedRef",BindingFlags.NonPublic|BindingFlags.Instance);varsizeValue=sizeField.GetValue(monitorValue);varapproxValue.GetType=size().GetProperty("ApproximateSize",BindingFlags.NonPublic|BindingFlags.Instance);返回(长)approxProp.GetValue(sizeValue,null);似乎在.NET4.6.1上运行良好,未经过广泛测试。这在陆地上可用,只是不要依赖它,因为它可能会随着任何.NET更新而中断。我使用了原始代码并做了一些小的调整,我使用“_sizedRefMultiple”而不是“_sizedRef”来使其与.NET4.6一起工作。公共静态类MemoryCacheHackExtensions{publicstaticlongGetApproximateSize(此MemoryCache缓存){varstatsField=typeof(MemoryCache).GetField(“_stats”,BindingFlags.NonPublic|BindingFlags.Instancevar);=statsValue.GetType().GetField("_cacheMemoryMonitor",BindingFlags.NonPublic|BindingFlags.Instance);varmonitorValue=monitorField.GetValue(statsValue);varsizeField=monitorValue.GetType().GetField("_sizedRefMultiple",BindingFlag|BindingFlags.Instance);varsizeValue=sizeField.GetValue(monitorValue);varapproxProp=sizeValue.GetType().GetProperty("ApproximateSize",BindingFlags.NonPublic|BindingFlags.Instance);返回(长)approxProp.GetValue(sizeValue,null);作为替代方案,您还可以实现IMemoryCacheManager接口并将其分配给全局ObjectCache.Host属性。这要求您被允许执行此操作,即您的应用程序中没有其他组件已经在执行此操作(想到ASP.NET,但我不确定)。就个人而言,我在控制台/Windows服务应用程序中使用该方法没有任何问题。另请注意,您只能在完整GC后获得缓存大小,但这与Hans的方法应该没有什么不同。另请注意,下面的代码适用于命名的MemoryCaches,即不适用于实例本身。颇有观点的“但是”。但是,它不需要反射。所以,这是代码。publicstaticclassMemoryCacheHelper{privatestaticreadonlyMemoryCacheServiceProviders_serviceProvider=newMemoryCacheServiceProvider();静态MemoryCacheHelper(){尝试{ObjectCache.Host=s_serviceProvider;}catch(InvalidOperationExceptionex){//ObjectCache.Host只能设置一次。}}publicstaticMemoryCacheCreate(stringname,NameValueCollectionconfig){returnnewMemoryCache(name,config);}//返回近似的缓存大小以及上次确定该值的时间。publicstaticTupleGetApproximateSize(stringname){returns_serviceProvider.GetApproximateSize(cache.Name);}privateclassMemoryCacheServiceProvider:IMemoryCacheManager,IServiceProvider{privatereadonlyobjectm_lock=newobject();privatereadonlyIDictionary>m_sizes=newDictionary>();publicTupleGetApproximateSize(stringname){lock(m_lock){元组信息;如果(m_sizes.TryGetValue(name,outinfo))返回信息;返回空值;}}无效IMemoryCacheManager.UpdateCacheSize(longsize,MemoryCachecache){lock(m_lock){//UpdateCacheSize()方法将根据为相应缓存配置的“pollingInterval”//调用。该值默认为2分钟。因此,此语句不会//??经常触发,并且作为积极的副作用,我们会得到某种“大小心跳”//可能在故障排除时有所帮助。m_sizes[cache.Name]=Tuple.Create(size,DateTime.UtcNow);}}voidIMemoryCacheManager.ReleaseCache(MemoryCachecache){lock(m_lock){m_sizes.Remove(cache.Name);}}objectIServiceProvider.GetService(TypeserviceType){if(serviceType==typeof(IMemoryCacheManager)){返回这个;}返回空值;如果您在性能方面寻找内存,则需要使用一些计数器,例如:所有堆中的字节数保留字节总数您可以使用Perfmon执行此操作,您可以参考此链接:http://msdn。microsoft.com/en-us/library/x2tyfybc(v=vs.110).aspx以这种方式衡量并不简单,但您会有很好的洞察力RobertoC#学习教程就这些:如何测量.NETMemoryCache4.0的当前大小?如果所有分享的内容对你有用,需要进一步了解C#学习教程,希望大家多多关注。本文收集自网络,不代表立场。如涉及侵权,请点击右侧联系管理员删除。如需转载请注明出处: