测试案例
string str1 = "Walker";
string str2 = "Walker";
string str3 = new string("Walker");
string str4 = new string("Walker");
Debug.LogErrorFormat("str1==str2:{0}", str1 == str2);
Debug.LogErrorFormat("str1 ref equal str2:{0}", ReferenceEquals(str1, str2));
Debug.LogErrorFormat("str3==str4:{0}", str3 == str4);
Debug.LogErrorFormat("str3 ref equal str4:{0}", ReferenceEquals(str3, str4));
测试结论
- C#中每创建一个string对象,都会分配一份新的内存。即便内容一样,地址也是不同的,占用两份内存。:由
ReferenceEquals(str3, str4)
得出结论 - 字面量直接赋值的string,取的对象来自于常量池,所以是同一个对象:由ReferenceEquals(str1, str2)得出结论
- 相等(==)的对象,不一定是同一个对象。这一点虽然大家都知道,但是到string这里还是容易被忽略。
延展结论
- Lua给C#传递的每个string对象都各自占用一份内存
- 从Unity对象中取到的每个string都各自占用一份内存,如GameObject.name
C#中没有默认给string建立缓存池,所以每个对象都是独立内存。可以通过
string cached = string.Intern(str);
手动给string建立缓存。但也要注意:
1、cached跟str不是同一块内存
2、缓存string的地方,要用Intern的返回值(cached),不能直接使用str
3、Intern并不能减少string的内存分配,只是用了它之后,驻留的内存会变少。如果一个string只是临时变量,不会缓存下来(如:作为Key索引某些对象),不要用Intern,会变负优化。