之前在开发中只用到List的时候几乎就是拿过来就用,从来没有考虑过List的内存分配问题,试想一个有10万元素的List的在构造和添加元素时内存是如何变化的呢?在MSDN上关于List的Capacity属性是这么解释的,也就是说,当我们添加的元素数量小于等于Capacity的值时,List是不会重新调整内部数据结构,也就是不会重新申请或者分配内存,而当我们添加的元素数量大于Capacity 的值时,List就会不断的调整内部数据结构或者重新申请分配内存,这样的话对效率肯定会有一定的影响的。

当我们使用List<T> list = new List<T>();实例化一个List对象是,.Net Framework只是在内存中申请了一块内存在存放list对象本身,系统此时并不知道list会有多少item元素。当我们向list添加第一个item时,list会申请能存储4个Item元素的存储空间,此时Capacity是4,但是当我们添加到第五个item时,此时的Capacity就会变成8,也就是当list发现元素的总数大于Capacity数量时,会主动申请并重新分配内存,当我们添加到第九个item时,Capacity不是12而是16,也就是说list每次申请的内存数量都是之前item元素数量两倍。然后将当前所有的item元素系但添加的元素复制到新的内存。

大家可以看到,如果list需要添加的元素特别多时,list会不断地申请心内存,复制已有元素和新加元素到新内存,这个过程会产生资源的浪费及性能问题。

如果当设置的Capacity值远大于list的实际元素数量时,应使用TrimExcess()方法释放点未使用的内存。

class Program
{
static void Main(string[] args)
{
List<Part> parts = new List<Part>(); Console.WriteLine("\nCapacity: {0}", parts.Capacity); parts.Add(new Part() { PartName = "crank arm", PartId = 1234 });
parts.Add(new Part() { PartName = "chain ring", PartId = 1334 });
parts.Add(new Part() { PartName = "seat", PartId = 1434 });
parts.Add(new Part() { PartName = "cassette", PartId = 1534 });
parts.Add(new Part() { PartName = "shift lever", PartId = 1634 }); Console.WriteLine(); foreach (Part aPart in parts)
{
Console.WriteLine(aPart);
} Console.WriteLine("\nCapacity: {0}", parts.Capacity);
Console.WriteLine("Count: {0}", parts.Count); parts.TrimExcess();
Console.WriteLine("\nTrimExcess()");
Console.WriteLine("Capacity: {0}", parts.Capacity);
Console.WriteLine("Count: {0}", parts.Count); parts.Clear();
Console.WriteLine("\nClear()");
Console.WriteLine("Capacity: {0}", parts.Capacity);
Console.WriteLine("Count: {0}", parts.Count); Console.Read();
}
} public class Part
{
public string PartName { get; set; }
public int PartId { get; set; }
public override string ToString()
{
return "ID: " + PartId + " Name: " + PartName;
}
}

知道了list的Capacity及TrimExcess()方法的用处,保证有限的内存空间能够得到合理的运行,归纳起来主要有以下几点:

1.当我们实例化一个List对象时,如果知道最大的Item元素时,应该在实例化List<T>时制定Capacity的数量,直接使用List的构造方法public List(int capacity);就可以。

2.当由于不断的从list中remove掉大量元素时,此时list内存仍占用一部分不需要使用的空间,造成内存的浪费,此时可以调用TrimExcess方法来释放多余的内存。

以上是我对list的内存分配一点浅显的理解,还请大家多多指教,欢迎拍砖。

List的Capacity,了解一下的更多相关文章

  1. 大数据之Yarn——Capacity调度器概念以及配置

    试想一下,你现在所在的公司有一个hadoop的集群.但是A项目组经常做一些定时的BI报表,B项目组则经常使用一些软件做一些临时需求.那么他们肯定会遇到同时提交任务的场景,这个时候到底如何分配资源满足这 ...

  2. List的Capacity

    Capacity 在.NET中List的容量应该只是受到硬件限制. 属性Capacity的真正含义,是创建List时给它预分配的容量. 一旦项的数量超过了当前的Capacity,Capacity会以 ...

  3. Hadoop Capacity Scheduler源码实现剖析

    作者: 大圆那些事 | 文章可以转载,请以超链接形式标明文章原始出处和作者信息 网址: http://www.cnblogs.com/panfeng412/archive/2013/09/13/had ...

  4. Sizing and Capacity Planning for SharePoint 2013 - Resources

    http://blogs.msdn.com/b/sanjaynarang/archive/2013/04/06/sizing-and-capacity-planning-for-sharepoint- ...

  5. 用了skin皮肤控件之后,报错:容量超出了最大容量 参数名:capacity

    http://blog.csdn.net/keenweiwei/article/details/7403869 用了皮肤控件之后,报错:容量超出了最大容量 参数名:capacity MessageBo ...

  6. Capacity Scheduler 队列设置

    先附一个官网地址 Capacity Scheduler是YARN中默认的资源调度器. 相关参数配置: 资源分配相关参数 ``` (1) capacity:队列的资源容量(百分比). 当系统非常繁忙时, ...

  7. STL:string 大小(Size)和容量(Capacity)

    strings存在三种“大小”: 1.size()和length() 返回string中现在的字符个数.上述两个函数等效. 成员函数empty()用来检验字符数是否为0,亦即字符串是否为空.你应该优先 ...

  8. hdu 1839 Delay Constrained Maximum Capacity Path 二分/最短路

    Delay Constrained Maximum Capacity Path Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://acm.hdu. ...

  9. Web Capacity Analysis Tool 压力测试工具使用笔记

    一.背景介绍 Web Capacity Analysis Tool是微软轻量级Web压力测试工具, 早先是IIS 6.0Resource Tool kit 工具包中的一个组件,现在独立出来有一个社区版 ...

  10. max_size, capacity and size 的区别

    The max_size() function returns the maximum number of elements that the container can hold. The max_ ...

随机推荐

  1. TLS反调试

    0x01 TLS反调试简介 TLS(Thread Local Storage)原本的目的是解决多线程程序中变量同步的问题.线程本身有独立于其他线程的栈空间,因此线程中的局部变量不用考虑同步问题.多线程 ...

  2. 网口扫盲二:Mac与Phy组成原理的简单分析(转)

    1. general 下图是网口结构简图.网口由CPU.MAC和PHY三部分组成.DMA控制器通常属于CPU的一部分,用虚线放在这里是为了表示DMA控制器可能会参与到网口数据传输中. 对于上述的三部分 ...

  3. CentOS7安装配置Bacula yum方法

    参考: https://www.baidu.com/link?url=o2QIy2YZWjsJPAFJuYFhrH3nPvtyRkSe-o5Q_FqFZ5E1EMOsIOmGeKm0HAonwHOw8 ...

  4. Effective Java (ENUM篇)

    我们存放一些静态变量,像是一些变量和设置,等等等等,我们尽量使用ENUM,因为ENUM是不可实例化和继承的,所以他很安全,它是在程序一开始运行的时候进行一些编译,修改ENUM不需要再次编译. 在什么时 ...

  5. ob 函数的使用

    ob 函数的使用1. 页面静态化 $id = isset($_GET['id'])?$_GET['id']-0:0; $filename = "html/".date(" ...

  6. mysql 转义字符问题

    首先我们要知道,数据库都是由表构成的,当你把数据插入到其中的一个表中的时候,比如是数字呀.文字呀等等的插入的时候能正常插入,但是一旦你要插入特殊的字符,比如说插入下面这个括号里面的内容(“ABC”)到 ...

  7. Mysql数据库文件迁移并修改默认数据文件存储位置

    环境: 1.两台Win10电脑 2.MySql5.6 过程: 1.原电脑停止MySql服务 2.复制C:\ProgramData\MySQL\MySQL Server 5.6\data文件夹到目标电脑 ...

  8. codeforce 839A Arya and Bran(水题)

    Bran and his older sister Arya are from the same house. Bran like candies so much, so Arya is going ...

  9. 基于区域的OSPF的MD5认证

    实验要求:掌握OSPF基于区域的MD5认证 拓扑如下: 配置如下: R1enable configure terminal interface s0/0/0ip address 192.168.1.1 ...

  10. 如何在Ubuntu/Linux内使用 zip 压缩隐藏文件?

    假设你的当前目录结构为: A文件--B文件夹--C文件等 | | D文件夹-E文件 | | 等等文件(含隐藏) 那么在使用zip命令时加上 -r 即可包含整个目录结构和隐藏文件: zip -r B.z ...