gpt4 book ai didi

c# - 大型数组中的内存泄漏 - 子类化 IList 会修复它吗?

转载 作者:太空狗 更新时间:2023-10-30 01:11:33 24 4
gpt4 key购买 nike

我需要提高我的应用程序的内存性能,我发现我遇到了内存碎片问题。

我读过 interesting article on large objects来自 Red Gate 的 Andrew Hunter,他推荐的解决方案之一是:

If large data structures need to live for a long time, and especially if they need to grow in size over time, the best approach is simply to consider using or writing a different data structure to store them. Arrays can contain up to around 10,000 elements before they are put on the large object heap and can cause problems, so a very effective way to store 100,000 entries might be to store 10 arrays each containing 10,000 elements: none will end up on the large object heap so no fragmentation will occur. This could be written as an IList subclass, which would make it easy to drop in transparently to replace existing code.

我如何在我的代码中实现他的建议?

我的程序有一个非常复杂的形式(有一个对象,每次打开时都会留下残余内存。我发现一个复杂的列表可能是罪魁祸首,我想实现他的建议看看它是否解决了问题。

最佳答案

为此使用 List 有什么问题?这不过是 IList 的一个实现,您可以自己进行分区。但是如果你想透明地做到这一点:

实现 IList(它只是一个接口(interface),没有什么特别之处。也许我不明白这个问题?)并通过所需大小的数组对其进行备份。然后,您的 Get() 会将 index/sizeOfArrays 作为包含所需项的数组的索引,并返回 index % sizeOfArrays 中的第一项那个数组。


为了好玩,因为这是一个懒惰的星期五,我写了一些东西。注意:

  • 我没有测试
  • 我无法评论您引用的关于这可能有助于避免内存碎片的说法是否正确,我只是盲目地查看了您的请求
  • 我不知道 List 或任何其他集合是否已经足够聪明可以做到这一点
  • 我做了一些可能不适合你的决定(即,如果你现在正在使用数组,你不能盲目地将它放入你的代码中。查看 Item 实现,尤其是 setter,因为例子

也就是说,这是一个减少我周末前动机缺陷的起点。我给亲爱的读者(或 OP)留下了一些有趣的方法作为练习。.;-)

public class PartitionList<T> : IList<T> {
private readonly int _maxCountPerList;
private readonly IList<IList<T>> _lists;

public PartitionList(int maxCountPerList) {
_maxCountPerList = maxCountPerList;
_lists = new List<IList<T>> { new List<T>() };
}

public IEnumerator<T> GetEnumerator() {
return _lists.SelectMany(list => list).GetEnumerator();
}

IEnumerator IEnumerable.GetEnumerator() {
return GetEnumerator();
}

public void Add(T item) {
var lastList = _lists[_lists.Count - 1];
if (lastList.Count == _maxCountPerList) {
lastList = new List<T>();
_lists.Add(lastList);
}
lastList.Add(item);
}

public void Clear() {
while (_lists.Count > 1) _lists.RemoveAt(1);
_lists[0].Clear();
}

public bool Contains(T item) {
return _lists.Any(sublist => sublist.Contains(item));
}

public void CopyTo(T[] array, int arrayIndex) {
// Homework
throw new NotImplementedException();
}

public bool Remove(T item) {
// Evil, Linq with sideeffects
return _lists.Any(sublist => sublist.Remove(item));
}

public int Count {
get { return _lists.Sum(subList => subList.Count); }
}

public bool IsReadOnly {
get { return false; }
}

public int IndexOf(T item) {
int index = _lists.Select((subList, i) => subList.IndexOf(item) * i).Max();
return (index > -1) ? index : -1;
}

public void Insert(int index, T item) {
// Homework
throw new NotImplementedException();
}

public void RemoveAt(int index) {
// Homework
throw new NotImplementedException();
}

public T this[int index] {
get {
if (index >= _lists.Sum(subList => subList.Count)) {
throw new IndexOutOfRangeException();
}
var list = _lists[index / _maxCountPerList];
return list[index % _maxCountPerList];
}
set {
if (index >= _lists.Sum(subList => subList.Count)) {
throw new IndexOutOfRangeException();
}
var list = _lists[index / _maxCountPerList];
list[index % _maxCountPerList] = value;
}
}
}

关于c# - 大型数组中的内存泄漏 - 子类化 IList 会修复它吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2251535/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com