【发布时间】:2019-02-24 19:31:57
【问题描述】:
在我的应用程序中,我遇到了内存使用问题,Loh 充满了死对象,价值 1.5GB(见下文)。这些对象被存储在一个字节数组中。
我试图通过运行以下代码来清理它以减少内存使用,但它似乎没有运行。
private static void OnScavengeProfileCache(object data)
{
// loop until the runtime is shutting down
while(HostingEnvironment.ShutdownReason == ApplicationShutdownReason.None)
{
// NOTE: Right now we only do the scavenge when traffic is temporarily low,
// to try to amortize the overhead of scavenging the cache into a low utilization period.
// We also only scavenge if the process memory usage is very high.
if (s_timerNoRequests.ElapsedMilliseconds >= 10000)
{
// We dont want to scavenge under lock to avoid slowing down requests,
// so we get the list of keys under lock and then incrementally scan them
IEnumerable<string> profileKeys = null;
lock (s_profileCache)
{
profileKeys = s_profileCache.Keys.ToList();
}
ScavengeProfileCacheIncremental(profileKeys.GetEnumerator());
}
// wait for a bit
Thread.Sleep(60 * 1000);
}
}
private static void ScavengeProfileCacheIncremental(IEnumerator<string> profileKeys)
{
if (s_thisProcess.PrivateMemorySize64 >= (200 * 1024 * 1024) ) // 3Gb at least
{
int numProcessed = 0;
while(profileKeys.MoveNext())
{
var key = profileKeys.Current;
Profile profile = null;
if (s_profileCache.TryGetValue(key, out profile))
{
// safely check/remove under lock, its fast but makes sure we dont blow away someone currently being addded
lock (s_profileCache)
{
if (DateTime.UtcNow.Subtract(profile.CreateTime).TotalMinutes > 5)
{
// can clear it out
s_profileCache.Remove(key);
}
}
}
if (++numProcessed >= 10)
{
// stop this scan and check memory again
GCSettings.LargeObjectHeapCompactionMode = GCLargeObjectHeapCompactionMode.CompactOnce;
GC.Collect();
break;
}
}
}
}
关于我应该如何在这里清理内存使用的任何提示?
【问题讨论】:
-
您是否应该计算您未在此处删除的配置文件?
-
MemoryCache可能是正确的解决方案,因为数据会自动过期 - 您无需像在这里一样手动操作。 -
内存缓存对我来说是一个陌生的话题,关于如何实现它有什么建议吗? @mjwills
-
我建议阅读
MemoryCache的文档并尝试一下,然后创建一个包含任何具体问题的新问题。
标签: c# .net memory-management memory-leaks