一 内存
1.对象创建尽量放到后面
尽可能的把创建对象放到后面,可以节省内容和减少其生命周期
如:
LargeObject largeObject = new LargeObject();
// Long running database call ...
largeObject.MyMethod();
应该用下面的来进行替换:
// Long running database call ...
LargeObject largeObject = new LargeObject();
largeObject.MyMethod();
* 如果对象大小不超过85KB,则不用预先进行内存分配。可能预先分配内存空间在一些开发环境下是更有效率的,但是在有内存回收垃圾机制的.NET环境下是没有明显的益处的。相反,你这样做会阻止CLR更有效的管理内存。
*如果你使用的是.NET4,可以考虑使用 Lazy<T>,它可以实际使用到的时候创建。例如下面的:
Lazy<ExpensiveObject> expensiveObject = new Lazy<ExpensiveObject>();
它不会创建对象,只有当你第一次使用到它的时候才进行创建 expensiveObject.Value
2.尽早释放
如果你在短时间内使用到了一个对象,一定要保证对象不被长时间的进行引用,否则垃圾回收器则不进行回收,导致对象长时间驻留在内存中。
如果你需要从一个长期的对象引用一个短命的对象,当你不在引用短期对象时把它设置为nulll,例如下面的代码:
LargeObject largeObject = new LargeObject();
// Create reference from long lived object to new large object
longLivedObject.largeObject = largeObject;
// Reference no longer needed
longLivedObject.largeObject = null;
在一个类中,如果一个属性引用到了短期对象,而你接下来要进行一段时间的其他处理,用不到这个属性引用,则你可以把属性引用设置为null,如下所示:
private LargeObject largeObject { get; set; }
public void MyMethod()
{
largeObject = new LargeObject();
// some processing ...
largeObject = null;
// more lengthy processing ...
局部变量则不需要这样处理,因为编译器会知道一个变量什么时候不在使用
3.用StringBuilder连接字符串
Strings 是在堆里不可改变的对象,当你对一个字符串进行操作的时候,会自动在堆中创建一个新的对象,导致增加垃圾回收器的开销。
连接字符串是一个很常见的操作,StringBuilder类在命名空间System.Text 中,在连接字符串时不会在堆中产生中间字符串;它是先分配一个缓存,然后在缓存中对字符串进行操作。例如下面的代码:
Instead of the following:
string s = "";
for (int i = 0; i < stringArray.Length; i++)
{
s += stringArray[i];
}
Use the following:
StringBuilder sb = new StringBuilder(capacity);
for (int i = 0; i < stringArray.Length; i++)
{
sb.Append(stringArray[i]);
}
string s = sb.ToString();
• Instead of the following:
// Concatenation results in new string object
sb.Append(stringArray[i] + ",");
Use the following:
sb.Append(stringArray[i]);
sb.Append(",");
• Instead of the following:
// Returning a string creates an intermediate string on heap
sb.Append(ReturnString(...));
Use the following:
// Method itself adds string to StringBuilder
AddString(sb, ...);
4.什么情况下不使用StringBuilder
如果所连接的字符串个数小于7个,则不使用StringBuilder
StringBuilder 大小
StringBuilder 构造函数可以带有个 大小的参数,默认大小是16,每当StringBuilder大小超过默认大小时,它会自动分配一个比原来缓存大一倍的缓存,并把原来缓存的内存拷贝到新缓存中,把原来缓存交给垃圾回收器。
也就是说当然能够知道分配缓存为多大合适的情况下,你可以通过构造函数分配缓存大小。