Basic Windbg - 1. SOSBasics(总结)

原文地址: http://www.cnblogs.com/juqiang/archive/2008/01/02/1023291.html

Basic Windbg - 1. SOSBasics(总结)

我们都知道,对于字符串相加,建议使用StringBuilder,而不是普通的string concat,为什么呢?我们通过dump简单看一下。
先看这个代码:

 1using System;
 2using System.Collections.Generic;
 3using System.Text;
 4
 5namespace SOSBasics2
 6{
 7    class Program
 8    {
 9        static void Main(string[] args)
10        {
11            StringTest st = new StringTest();
12            long t1 = st.StringConcat("hello"10000);
13            long t2 = st.StringBuilder("world"10000);
14
15            Console.WriteLine("String concat cost: {0:N0}", t1);
16            Console.WriteLine("String builder cost: {0:N0}", t2);
17
18            Console.WriteLine("=========================================================");
19            Console.WriteLine("到命令行下面,然后切换到windbg目录,执行adplus -hang -pn sosbasics2.exe -o c:\\dumps");
20            Console.ReadLine();
21        }

22    }

23
24    public class StringTest
25    {
26        public long StringConcat(string input, int repeat)
27        {
28            long tick1 = DateTime.Now.Ticks;
29            string s = "";
30
31            for (int i = 0; i < repeat;i++)
32            {
33                s += input;
34            }

35
36            long tick2 = DateTime.Now.Ticks;
37
38            return tick2 - tick1;
39        }

40
41        public long StringBuilder(string input, int repeat)
42        {
43            long tick1 = DateTime.Now.Ticks;
44            StringBuilder sb = new StringBuilder();
45
46            for (int i = 0;i < repeat;i++)
47            {
48                sb.Append(input);
49            }

50
51            string s = sb.ToString();
52            long tick2 = DateTime.Now.Ticks;
53
54            return tick2 - tick1;
55        }

56    }

57}

58

对于hello字符串,我们加10000次,然后得到时间差。对于world字符串,我们也加10000次,然后得到时间差。按照前面讲的抓dump的方法,我们得到dump,然后看!dumpheap -stat的结果:
0:000> !dumpheap -stat
total 3686 objects
Statistics:
      MT    Count    TotalSize Class Name
791334a8        1           12 System.Collections.Generic.GenericEqualityComparer`1[[System.String, mscorlib]]
79119954        1           12 System.Security.Permissions.ReflectionPermission
79119834        1           12 System.Security.Permissions.FileDialogPermission

。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。
79104368      266         6384 System.Collections.ArrayList
7912d8f8      299        31408 System.Object[]
004ad640       31      1060716      Free
790fd8c4     2399      2423452 System.String
Total 3686 objects

然后我们看字符串的东西:!dumpheap -mt 790fd8c4 -strings(strings这个参数的意思是,只输出字符串,其他的都省略掉),结果如下:
0:000> !dumpheap -mt 790fd8c4 -strings
total 2399 objects
Statistics:
   Count    TotalSize String Value
       1           20 "}"
       1           20 "{"
       1           20 "x"

。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。
       2         5600 "<PermissionSet class="System.Security.NamedPermissionSet"versio"
       1         9280 "<NamedPermissionSets><PermissionSet class="System.Security.Name"
      10       262092 "worldworldworldworldworldworldworldworldworldworldworldworldwor"
      20      1998520 "hellohellohellohellohellohellohellohellohellohellohellohellohel"
Total 2399 objects


值得我们注意的是,world字符串(一大堆),一共有10个,大小是262092,hello字符串一共有20个,大小是1998520。两者为啥相差这么大?书上说,string concat会不停的产生临时对象,这些对象都会占用内存的,so,会比较慢,也比较吃内存。而StringBuilder是预先分配好了一块内存来用,so,会快一些。从上面的结果来看,貌似是这样的。
好,那我们修改一下代码吧!
Code
我们对StringBuilder的参数做点手脚,让它一次性的初始化64K大小,重新抓dump,然后重新用!dumpheap -mt和!dumpheap -stat来看。

       1       131096 "worldworldworldworldworldworldworldworldworldworldworldworldwor"
      20      1998520 "hellohellohellohellohellohellohellohellohellohellohellohellohel"
Total 2387 objects

这个结果比较有意思吧!如果我们让stringBuilder的buffer足够大,那么它可以避免频繁分配内存。这个例子来看,字符串只分配了两次而已(上面还有一个5个字节的,我没有列出)

你可能感兴趣的:(OS)