可能有5或6个SO帖子切向触及这个,但没有一个真正回答这个问题.
我有一个Dictionary对象,我使用一种缓存来存储值.问题是我不知道它有多大 - 随着时间的推移它可能会变得越来越大,但我无法分辨,所以我无法衡量它的有效性,或者对用户如何使用该软件做出结论.因为这是一个将在很长一段时间内投入生产并监控某些东西的部分,所以连接内存分析器或任何类似的调试都没有意义.
理想情况下,我只需在我的Timer中调用一个类似于:
private void someTimer_Tick(object sender, EventArgs e)
{
...
float mbMem = cacheMap.GetMemorySize();
RecordInLog(DateTime.Now.ToString() + ": mbMem is using " + mbMem.ToString() + "MB of memory");
...
}
Run Code Online (Sandbox Code Playgroud)
这可以在不附加某些调试工具的情况下完成,以便可以使用部署方案吗?
鉴于您最近的评论,该值是一个可变长度字符串,计算字典中每个项目的大小应该很容易。我会考虑通过创建自己的缓存对象(可能只是包装字典)并跟踪在缓存中添加和删除项目时的总大小来节省时间和精力。这样,在任何时间点,您都可以通过查看一直跟踪的值来了解缓存中值的总大小。
如果您需要缓存公开完整的IDictionary
功能,您可以实现该接口,委托给“真实”字典并修改Add
和Remove
操作中的累积大小值。如果您不需要缓存来公开完整的IDictionary
功能,只需定义一个精简的接口(可能只有Add
、Contains
、 和Remove
方法以及一个CumulativeSize
属性。或者,您可能决定实现一个没有接口的缓存对象。如果是我的话,我会使用IDictionary
或定义一个接口,例如ICache
.
因此,您的缓存可能看起来像这样(未编译和未经测试):
public interface ICacheWithCumulativeSize
{
void Add(string key, string value);
bool Contains(string key);
void Remove(string key);
int CumulativeSize { get; }
}
public class MyCache : ICacheWithCumulativeSize
{
private IDictionary<string, string> dict = new Dictionary<string, string>();
public void Add(string key, string value)
{
CumulativeSize += value.Length;
dict[key] = value;
}
public bool Contains(string key)
{
return dict.ContainsKey(key);
}
public void Remove(string key)
{
string toRemove = dict[key];
CumulativeSize -= value.Length;
dict.Remove(key);
}
int CumulativeSize { public get; private set; }
}
Run Code Online (Sandbox Code Playgroud)
这非常粗糙。显然,它可以更高效、更稳健。我没有进行任何检查Add
并Remove
查看密钥是否已经存在等,但我想您可能已经明白了。此外,作为值存储在字典中的字符串可能可以在外部进行修改(可能不在您的程序中,但理论上),因此从字符串中删除值时减去字符串的CumulativeSize
长度缓存可能与最初添加该字符串时的长度不同。如果这是一个问题,您可以考虑在内部字典中存储值的副本。我对你的申请了解不够,无法判断这是否是一个好主意。
为了完整起见...这是一个粗略的实现,它简单地包装了一个字典,公开了 IDictionary 接口,并跟踪缓存中项目的总大小。它有更多的防御性代码,主要是为了保护大小累加器。我可能认为棘手的唯一部分是索引设置器...我的实现检查所设置的索引是否已经存在。如果是,则根据输入值的大小适当递减累加值,然后递增。否则,我认为这非常简单。
public class MySpecialDictionary : IDictionary<string, string>
{
private IDictionary<string, string> dict = new Dictionary<string, string>();
public int TotalSize { get; private set; }
#region IDictionary<string,string> Members
public void Add(string key, string value)
{
dict.Add(key, value);
TotalSize += string.IsNullOrEmpty(value) ? 0 : value.Length;
}
public bool ContainsKey(string key)
{
return dict.ContainsKey(key);
}
public ICollection<string> Keys
{
get { return dict.Keys; }
}
public bool Remove(string key)
{
string value;
if (dict.TryGetValue(key, out value))
{
TotalSize -= string.IsNullOrEmpty(value) ? 0 : value.Length;
}
return dict.Remove(key);
}
public bool TryGetValue(string key, out string value)
{
return dict.TryGetValue(key, out value);
}
public ICollection<string> Values
{
get { return dict.Values; }
}
public string this[string key]
{
get
{
return dict[key];
}
set
{
string v;
if (dict.TryGetValue(key, out v))
{
TotalSize -= string.IsNullOrEmpty(v) ? 0 : v.Length;
}
dict[key] = value;
TotalSize += string.IsNullOrEmpty(value) ? 0 : value.Length;
}
}
#endregion
#region ICollection<KeyValuePair<string,string>> Members
public void Add(KeyValuePair<string, string> item)
{
dict.Add(item);
TotalSize += string.IsNullOrEmpty(item.Value) ? 0 : item.Value.Length;
}
public void Clear()
{
dict.Clear();
TotalSize = 0;
}
public bool Contains(KeyValuePair<string, string> item)
{
return dict.Contains(item);
}
public void CopyTo(KeyValuePair<string, string>[] array, int arrayIndex)
{
dict.CopyTo(array, arrayIndex);
}
public int Count
{
get { return dict.Count; }
}
public bool IsReadOnly
{
get { return dict.IsReadOnly; }
}
public bool Remove(KeyValuePair<string, string> item)
{
string v;
if (dict.TryGetValue(item.Key, out v))
{
TotalSize -= string.IsNullOrEmpty(v) ? 0 : v.Length;
}
return dict.Remove(item);
}
#endregion
#region IEnumerable<KeyValuePair<string,string>> Members
public IEnumerator<KeyValuePair<string, string>> GetEnumerator()
{
return dict.GetEnumerator();
}
#endregion
#region IEnumerable Members
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
{
return dict.GetEnumerator();
}
#endregion
}
Run Code Online (Sandbox Code Playgroud)
祝你好运!