我有将近1,000,000条记录的数组,每条记录都有一个字段"filename“。
有许多记录具有完全相同的文件名。
我的目标是通过对字符串实例(文件名实例,而不是记录)进行重复数据删除来提高内存占用。
.NET Framework2.0是一个约束。这里没有LINQ。
我为重复数据删除写了一个通用的(并且线程安全的)类:
public class Deduplication<T>
where T : class
{
private static Deduplication<T> _global = new Deduplication<T>();
public static Deduplication<T> Global
{
get { return _global; }
}
private Dictionary<T, T> _dic;// = new Dictionary<T, T>();
private object _dicLocker = new object();
public T GetInstance(T instance)
{
lock (_dicLocker)
{
if (_dic == null)
{
_dic = new Dictionary<T, T>();
}
T savedInstance;
if (_dic.TryGetValue(instance, out savedInstance))
{
return savedInstance;
}
else
{
_dic.Add(instance, instance);
return instance;
}
}
}
public void Clear()
{
lock (_dicLocker)
{
_dic = null;
}
}
}这个类的问题是它增加了更多的内存使用,并且它会一直保持到下一次GC。
我在寻找一种方法来减少内存占用,而不需要增加更多的内存使用,也不需要等待下一次GC。另外,我不想使用GC.Collect(),因为它会冻结图形用户界面几秒钟。
发布于 2015-01-15 23:36:50
如果你不想插手你的弦。您可以对Java 8的字符串重复数据删除采取类似的方法(这是由堆上的GC完成的)。
假设您有很多重复项,这将减少您的内存占用,但实例化可能会执行得更好,因为它是在堆的较低级别上完成的。
发布于 2013-09-13 11:57:06
你可以把所有的字符串放在一个前缀树中。根据路径名的不同,这应该会自动删除通用子字符串的重复数据。在谷歌上快速搜索一下,得到的结果是this C# implementation。
发布于 2013-09-13 07:43:20
我建议您仔细检查您的内存占用是否已经优化。.NET会自动在堆上实例化重复的字符串,这意味着您可以让多个相同的String对象指向相同的内存地址。打电话给String.Intern(targetString)就行了。这就是为什么String是不可变的,而StringBuilder是存在的。
更直接的是,如果堆上的剩余字符串出现问题,可以在完成后立即启动垃圾收集(甚至在运行期间定期启动):
GC.Collect();
https://stackoverflow.com/questions/18775932
复制相似问题