C#List< string>内存未收集 [英] C# List<string> Memory not collected

查看:55
本文介绍了C#List< string>内存未收集的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

此代码分配内存,但从不释放内存.我如何强制收集内存,GC.Collect()似乎也不起作用.

This code allocates memory, but never frees the memory. How do I force collection of the memory, GC.Collect() does not seem to work either.

我复查了许多发问这个问题的帖子,但每个人都回答说垃圾收集器将处理内存,但从来没有.

I have reviewed many posts that ask this question but everyone answers that the garbage collector will take care of the memory, but it never does.

    var list = new List<string>();

    for (var i = 0; i < 10000000; i++)
    {
      list.Add("really long string..................................................................................................");
    }

    for (var i = 0; i < 10000000; i++)
    {
      list[i] = null;
    }

    list.Clear();

推荐答案

以下是 List<T>.Clear 的代码:

Here's the code of List<T>.Clear:

// Clears the contents of List.
public void Clear() {
    if (_size > 0)
    {
        Array.Clear(_items, 0, _size); // Don't need to doc this but we clear the elements so that the gc can reclaim the references.
        _size = 0;
    }
    _version++;
}

如您所见,该数组保持原样分配.这样做是出于效率方面的考虑.该数组已分配完毕,无需让GC收集它,因为可能会再次需要它.

As you can see, the array is kept allocated as-is. This is done for efficiency reasons. The array is already allocated, there's no need let the GC collect it as it will probably be needed again.

您可以设置Capacity属性,以强制其重新分配新的数组.实际上,这将增加内存压力(除非您将其设置为0),直到收集到先前的数组为止.这是代码以供参考:

You can set the Capacity property to force it to reallocate a new array. This will actually add memory pressure (unless you set it to 0) until the previous array gets collected. Here's the code for reference:

// Gets and sets the capacity of this list.  The capacity is the size of
// the internal array used to hold items.  When set, the internal 
// array of the list is reallocated to the given capacity.
// 
public int Capacity {
    get {
        Contract.Ensures(Contract.Result<int>() >= 0);
        return _items.Length;
    }
    set {
        if (value < _size) {
            ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.value, ExceptionResource.ArgumentOutOfRange_SmallCapacity);
        }
        Contract.EndContractBlock();

        if (value != _items.Length) {
            if (value > 0) {
                T[] newItems = new T[value];
                if (_size > 0) {
                    Array.Copy(_items, 0, newItems, 0, _size);
                }
                _items = newItems;
            }
            else {
                _items = _emptyArray;
            }
        }
    }
}

对于您的真的很长的字符串,它只是对一个嵌入字符串的引用...无论如何,该列表将为每个项目存储8个字节(假设使用64位系统).

As for your really long string, it's just a reference to an interned string... The list will store 8 bytes per item anyway (assuming a 64-bit system).

这篇关于C#List&lt; string&gt;内存未收集的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆