<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Mingbo &#187; 查缺补漏</title>
	<atom:link href="http://shao.mingbo.de/tag/%e6%9f%a5%e7%bc%ba%e8%a1%a5%e6%bc%8f/feed/" rel="self" type="application/rss+xml" />
	<link>http://shao.mingbo.de</link>
	<description>包括教育技术，编程，互联网等方面的文章及随想。</description>
	<lastBuildDate>Thu, 26 Aug 2010 02:57:15 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=abc</generator>
		<item>
		<title>cSharp编程基础的学习笔记</title>
		<link>http://shao.mingbo.de/2009/11/25/basical-knowledge-of-csharp/</link>
		<comments>http://shao.mingbo.de/2009/11/25/basical-knowledge-of-csharp/#comments</comments>
		<pubDate>Tue, 24 Nov 2009 17:00:37 +0000</pubDate>
		<dc:creator>邵 明博</dc:creator>
				<category><![CDATA[.NET 编程]]></category>
		<category><![CDATA[csharp]]></category>
		<category><![CDATA[myNote]]></category>
		<category><![CDATA[基础]]></category>
		<category><![CDATA[查缺补漏]]></category>

		<guid isPermaLink="false">http://shao.mingbo.de/?p=235</guid>
		<description><![CDATA[在上次写完了《垃圾回收机制的剖析》之后，就感觉这种做笔记的方法挺有意思的。于是打算把这作为一种习惯，坚持下来。下面记录的是今天看书的一点点收获。 编译运行： Main方法要么没有返回值Void，要么返回一个整数（int）。 修饰符static表示不能在类的实例上执行，因此不必先实例化类再调用（使用类本身的名称）。要访问一个实例字段，就需要使用this关键字。 变量-&#62;变量的初始化： 变量为类或结构的字段，如未初始化，创建这些变量时，其值就默认是0 方法的局部变量必须在代码中显式初始化，否则编译通不过。 常量-&#62;常量的特征： 常量总是静态的，不必也不允许在声明时包含修饰符static。 不能从一个变量提取值来初始化常量。如需相同的效果，可以使用只读变量。 预定义数据类型： c#中把数据类型分为2种，一种是值类型，另一种是引用类型。值类型储存在堆栈中，而引用类型储存在托管堆中。引用类型与值类型的区别参考以下代码： //引用类型给出的demo int[] x, y; x=new int[10]; x[0] = 10; y = x; y[0] = 20; Console.WriteLine(x[0]); //值类型给出的demo bool a, b; a = true; b = a; b = false; Console.WriteLine(a); 这个例子的输出结果是20和True.它说明，这2个引用变量虽然进行了赋值，但托管堆中只保留了一个引用，都指向了同一块区域。而值类型则不同，当一个布尔类型变量a赋值为true之后，再将a的值赋值给b,堆栈中就会有2个布尔值。 c#认可的基本预定义类型没有内置于c#语言中，而是内置于.net Framework中。当声明一个int类型的数据时，实际上是声明了一个System.Int32的一个实例。目前看来这样的做法，有这样的好处： 为多语言的交互铺路，形成了一个Common Type System。 使得基本的数据类型可以看做是支持某些方法的类，其声明出来的数据是支持这些方法的实例。如: int i = 10; string str [...]]]></description>
			<content:encoded><![CDATA[<p>在上次写完了《<a href="http://shao.mingbo.de/2009/11/23/dot-net-garbage-collector-analysis/">垃圾回收机制的剖析</a>》之后，就感觉这种做笔记的方法挺有意思的。于是打算把这作为一种习惯，坚持下来。下面记录的是今天看书的一点点收获。<br />
编译运行：</p>
<ul>
<li>Main方法要么没有返回值Void，要么返回一个整数（int）。</li>
<li>修饰符static表示不能在类的实例上执行，因此不必先实例化类再调用（使用类本身的名称）。要访问一个实例字段，就需要使用this关键字。</li>
</ul>
<p>变量-&gt;变量的初始化：</p>
<ul>
<li>变量为类或结构的字段，如未初始化，创建这些变量时，其值就默认是0</li>
<li>方法的局部变量必须在代码中显式初始化，否则编译通不过。</li>
</ul>
<p>常量-&gt;常量的特征：</p>
<ul>
<li>常量总是静态的，不必也不允许在声明时包含修饰符static。</li>
<li>不能从一个变量提取值来初始化常量。如需相同的效果，可以使用<strong>只读变量</strong>。</li>
</ul>
<p>预定义数据类型：</p>
<p>c#中把数据类型分为2种，一种是值类型，另一种是引用类型。值类型储存在堆栈中，而引用类型储存在托管堆中。引用类型与值类型的区别参考以下代码：</p>
<pre lang="csharp">            //引用类型给出的demo
            int[] x, y;
            x=new int[10];
            x[0] = 10;
            y = x;
            y[0] = 20;
            Console.WriteLine(x[0]);
            //值类型给出的demo
            bool a, b;
            a = true;
            b = a;
            b = false;
            Console.WriteLine(a);</pre>
<p>这个例子的输出结果是20和True.它说明，这2个引用变量虽然进行了赋值，但<strong>托管堆中只保留了一个引用</strong>，都指向了同一块区域。而值类型则不同，当一个布尔类型变量a赋值为true之后，再将a的值赋值给b,<strong>堆栈中就会有2个布尔值</strong>。</p>
<p>c#认可的基本预定义类型没有内置于c#语言中，而是内置于.net Framework中。当声明一个int类型的数据时，实际上是声明了一个System.Int32的一个实例。目前看来这样的做法，有这样的好处：</p>
<ul>
<li>为多语言的交互铺路，形成了一个Common Type System。</li>
<li>使得基本的数据类型可以看做是支持某些方法的类，其声明出来的数据是支持这些方法的实例。如:</li>
</ul>
<pre lang="csharp">            int i = 10;
            string str = i.ToString();
            Console.WriteLine(str);</pre>
<p>c#有15个预定义类型，13个是值类型，2个引用类型：string,object：</p>
<ul>
<li>所有的整数类型的变量都可以赋予十进制或十六进制的值。</li>
<li>对一个整数是int,uint,long或ulong没有显示的声明，都默认为int。（显示的声明可以在数字后面加上L或UL）</li>
<li>代码中没有对某个非整数类型硬编码，则默认为一个double类型。</li>
<li>decimal不是基本类型，所以在计算时使用会有性能的损失。</li>
<li>char包含16位。一部分原因是不允许char和byte进行隐式的转换；另外，尽管8位足够编码英语中的每个字符和数字0~9，<strong>但不能够编码更大的符号系统中的每个字符</strong>（如：中文）。为了面向全世界，计算机行业正从8位字符集向16位的Unicode模式转变。</li>
</ul>
<pre lang="csharp">            string a = "a string";
            string b = a;
            Console.WriteLine("a is "+a);
            Console.WriteLine("b is "+b);
            a = "another string";
            Console.WriteLine("a is "+a);
            Console.WriteLine("b is "+b);</pre>
<p><a href="http://shao.mingbo.de/wp-content/uploads/2009/11/类型.jpeg"><img class="alignleft size-thumbnail wp-image-246" title="类型" src="http://shao.mingbo.de/wp-content/uploads/2009/11/类型-150x150.jpg" alt="类型 150x150 cSharp编程基础的学习笔记" width="150" height="150" /></a>这是我总结的c#预定义类型的mindmap，大致囊括了各个类型的基本信息。其中string类型稍微有点特殊，这里单独抽出来谈谈，尤其注意到string是预定义类型中为数不多的引用类型，代码如上。挺有意思的是，按照之前引用类型与数值类型比较的例子得出的结论，最后一条应该输出“b is another string”。可事实并不是我们想象的那样。虽然string对象保留在堆上，但string的一些常用操作会与其他引用类型有所区别：<strong>修改一个字符串，就会创建一个全新的string对象</strong>。修改a的值，不是替换了原先的，而是在堆上重新分配了一个新的对象。——这是运算符重载造成的。</p>
<p>流控制：<br />
foreach循环不能修改集合中各项数据的值。虽然这个规则并不是知识体系中的漏洞，但作为之前接触不多的循环结构，还是要总结出来提醒自己。</p>
<h3  class="related_post_title">相关文章</h3><ul class="related_post"><li>2009年12月22日 -- <a href="http://shao.mingbo.de/2009/12/22/how-to-use-backgroundworker-in-csharp/" title="cSharp中BackgroundWorker的用法">cSharp中BackgroundWorker的用法</a></li><li>2009年12月21日 -- <a href="http://shao.mingbo.de/2009/12/21/synchronize-class-design-in-csharp/" title="cSharp中同步类的设计">cSharp中同步类的设计</a></li><li>2009年12月20日 -- <a href="http://shao.mingbo.de/2009/12/20/paralize-thread-in-charp/" title="cSharp中给线程传递参数">cSharp中给线程传递参数</a></li><li>2009年12月19日 -- <a href="http://shao.mingbo.de/2009/12/19/asynchronous-delegate-in-csharp/" title="cSharp中异步委托的笔记">cSharp中异步委托的笔记</a></li><li>2009年12月16日 -- <a href="http://shao.mingbo.de/2009/12/16/dynamic-loading-assemblies-and-reflection-in-csharp/" title="cSharp动态调用和反射的一个绝佳例子">cSharp动态调用和反射的一个绝佳例子</a></li></ul>]]></content:encoded>
			<wfw:commentRss>http://shao.mingbo.de/2009/11/25/basical-knowledge-of-csharp/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>.net垃圾回收的剖析</title>
		<link>http://shao.mingbo.de/2009/11/23/dot-net-garbage-collector-analysis/</link>
		<comments>http://shao.mingbo.de/2009/11/23/dot-net-garbage-collector-analysis/#comments</comments>
		<pubDate>Mon, 23 Nov 2009 09:37:54 +0000</pubDate>
		<dc:creator>邵 明博</dc:creator>
				<category><![CDATA[.NET 编程]]></category>
		<category><![CDATA[csharp]]></category>
		<category><![CDATA[dot net]]></category>
		<category><![CDATA[垃圾回收]]></category>
		<category><![CDATA[查缺补漏]]></category>

		<guid isPermaLink="false">http://shao.mingbo.de/?p=218</guid>
		<description><![CDATA[看了好几本.net专著，每一本都会提到.net的垃圾回收机制，而且，每一本都会不约而同的告诉你:&#8221;垃圾回收的一个重要方面是它的不确定性。换而言之,不能保证什么时候会调用垃圾收集器&#8230;&#8221;。看到这里，你会很自然的对这个“不确定性”感兴趣——既然不确定，.net又是怎么保证垃圾在很大程度上被回收的呢？这个垃圾回收机制能否有一个更加完善的版本呢？ 在.net之前,windows平台已经用了2种技术来释放进程向系统动态请求的内存： 完全手工的方式。 让对象维护引用计数。 完全手工的方式的一个经典例子，便是大名鼎鼎的c++.它能够很有效的释放内存，但缺点是容易频繁的出错，内存泄露时有发生。尽管现代的开发环境提供了内存泄露检测工具，但它们很难跟踪错误，因为直到内存已大量泄露使得windows拒绝服务时，它们才能发挥作用；让对象维护引用计数，是COM对象采用的一种技术。每个COM对象都保留一个客户机对自己的引用计数。当这个计数下降到0的时候，组件就会自己删除自己，并释放相应的内存和资源。但，如果客户机没有通知成功，那么COM对象便一直停留在内存。这一点比起C++内存泄露更为可怕。因为，一旦C++的进程被迫结束时也会释放相应的内存和资源，而COM对象占用的内存可能一直都不会被系统删除，直到你重新启动。 .net采用的垃圾回收就很好的规避了上述的缺点。 和所有语言一样，所有动态请求的内存都会分布在堆上，而.net是放到自己的CLR托管堆上。为了便于理解，我们先讨论一个简化的垃圾回收模型： 这个模型遵循以下规则： 所有的对象都分配到一个连续的内存空间。 堆被分割成了若干个等级，以便于我们能够只观察某一等级的堆，就能最大可能的清除最多的垃圾。 存储在同一等级的堆中的对象，大致上具有相同的生命周期。 等级越高的堆中，所存放的对象越稳定。 周期性的移动对象，以扩展未使用区域的内存。 对象在内存的顺序与创建的它们的顺序是相同的。 这里需要解释的是：.net垃圾回收器将堆分为了3个等级（generation0,1,2），对应的托管堆的初始化大小是256k,2M,10M。最近被分配的内存空间的对象被放置在第0代，一般存储于二级缓存中，所以能对第0代中的对象实现快速存取。经过一轮垃圾回收后，仍然保留在第0代中的对象则被移进第1代中，再经过一轮垃圾回收后，仍然保留再第1代中的对象则被移进第2代中，第2代中包含了生存期较长的对象，这些对象至少经过了两轮回收。 从这样等级制度中，我们不难给出下面的假设： 生命周期越长的对象需要释放的可能性越小, 通过几轮垃圾回收后,它们被存放到了Gen 2里，相比起刚分配内存的那些对象而言，G2的对象不太可能是下一个被释放的人选。因此，大多数情况下，我们收集垃圾时，忽略G2的内存堆，而搜索最近被分配的对象集合有助于花费最少的工作来释放尽可能多的空闲内存空间。 当然，假设永远是一个假设。我们不能保证G2中没有对象不需要释放的。因此.net回收机制设置了一个card table&#38;wrtie barrier的算法来尽力的保证回收的有效性。CT你可以理解为一段连续的内存，比如128byte.每当程序需要写入一块内存时，他会通过WB计算哪一块可以被写,就可以发现被修改了的G2对象，然后在ct中进行设置。通过这样的机制，当我们处理完等级为0的堆后，就可以在CT中寻找已经被修改了的对象。从而有效的完成垃圾回收。 但，事无完美，一旦CT内存被大量的G2对象占满时，则上述机制运行无效。但绝大多数情况下，G2对象是稳定的。这样，也能够解释，大多数的.net书籍会那么介绍垃圾回收机制了。当然是否有更好的机制，那得看聪明的您了。 参考资料： 《Professional C# 2008》Christian Nagel，Bill Evjen@  Wiley Publishing, Inc. MSDN doc:  相关文章2009年11月25日 -- cSharp编程基础的学习笔记2009年12月22日 -- cSharp中BackgroundWorker的用法2009年12月21日 -- cSharp中同步类的设计2009年12月20日 -- cSharp中给线程传递参数2009年12月19日 -- cSharp中异步委托的笔记]]></description>
			<content:encoded><![CDATA[<p style="text-align: left;">看了好几本.net专著，每一本都会提到<strong>.net的垃圾回收</strong>机制，而且，每一本都会不约而同的告诉你:&#8221;垃圾回收的一个重要方面是它的不确定性。换而言之,不能保证什么时候会调用垃圾收集器&#8230;&#8221;。看到这里，你会很自然的对这个“不确定性”感兴趣——既然不确定，.net又是怎么保证垃圾在很大程度上被回收的呢？这个垃圾回收机制能否有一个更加完善的版本呢？</p>
<p style="text-align: left;">在.net之前,windows平台已经用了2种技术来释放进程向系统动态请求的内存：</p>
<ul style="text-align: left;">
<li>完全手工的方式。</li>
<li>让对象维护引用计数。</li>
</ul>
<p style="text-align: left;">完全手工的方式的一个经典例子，便是大名鼎鼎的c++.它能够很有效的释放内存，但缺点是容易频繁的出错，内存泄露时有发生。尽管现代的开发环境提供了内存泄露检测工具，但它们很难跟踪错误，因为直到内存已大量泄露使得windows拒绝服务时，它们才能发挥作用；让对象维护引用计数，是COM对象采用的一种技术。每个COM对象都保留一个客户机对自己的引用计数。当这个计数下降到0的时候，组件就会自己删除自己，并释放相应的内存和资源。但，如果客户机没有通知成功，那么COM对象便一直停留在内存。这一点比起C++内存泄露更为可怕。因为，一旦C++的进程被迫结束时也会释放相应的内存和资源，而COM对象占用的内存可能一直都不会被系统删除，直到你重新启动。</p>
<p style="text-align: left;">.net采用的垃圾回收就很好的规避了上述的缺点。</p>
<p style="text-align: left;">和所有语言一样，所有动态请求的内存都会分布在堆上，而.net是放到自己的CLR托管堆上。为了便于理解，我们先讨论一个简化的垃圾回收模型：</p>
<p style="text-align: center;"><a href="http://shao.mingbo.de/wp-content/uploads/2009/11/Garbage-Collector-Basics-and-Performance-Hints.bmp"><img class="size-full wp-image-222 alignnone" title="Garbage-Collector-Basics-and-Performance-Hints" src="http://shao.mingbo.de/wp-content/uploads/2009/11/Garbage-Collector-Basics-and-Performance-Hints.bmp" alt="Garbage Collector Basics and Performance Hints .net垃圾回收的剖析"  /></a></p>
<p style="text-align: left;">这个模型遵循以下规则：</p>
<ul style="text-align: center;">
<li style="text-align: left;">所有的对象都分配到一个连续的内存空间。</li>
<li style="text-align: left;">堆被分割成了若干个等级，以便于我们能够只观察某一等级的堆，就能最大可能的清除最多的垃圾。</li>
<li style="text-align: left;"><span style="color: #ff0000;">存储在同一等级的堆中的对象，大致上具有相同的生命周期。</span></li>
<li style="text-align: left;">等级越高的堆中，所存放的对象越稳定。</li>
<li style="text-align: left;">周期性的移动对象，以扩展未使用区域的内存。</li>
<li style="text-align: left;">对象在内存的顺序与创建的它们的顺序是相同的。</li>
</ul>
<p>这里需要解释的是：<strong>.net垃圾回收器</strong>将堆分为了3个等级（generation0,1,2），对应的托管堆的初始化大小是256k,2M,10M。最近被分配的内存空间的对象被放置在第0代，一般存储于二级缓存中，所以能对第0代中的对象实现快速存取。经过一轮垃圾回收后，仍然保留在第0代中的对象则被移进第1代中，再经过一轮垃圾回收后，仍然保留再第1代中的对象则被移进第2代中，第2代中包含了生存期较长的对象，这些对象至少经过了两轮回收。</p>
<p>从这样等级制度中，我们不难给出下面的假设：</p>
<p>生命周期越长的对象需要释放的可能性越小, 通过几轮垃圾回收后,它们被存放到了Gen 2里，相比起刚分配内存的那些对象而言，G2的对象不太可能是下一个被释放的人选。因此，大多数情况下，我们收集垃圾时，忽略G2的内存堆，而搜索最近被分配的对象集合有助于花费最少的工作来释放尽可能多的空闲内存空间。</p>
<p>当然，假设永远是一个假设。我们不能保证G2中没有对象不需要释放的。因此.net回收机制设置了一个card table&amp;wrtie barrier的算法来尽力的保证回收的有效性。CT你可以理解为一段连续的内存，比如128byte.每当程序需要写入一块内存时，他会通过WB计算哪一块可以被写,就可以发现被修改了的G2对象，然后在ct中进行设置。通过这样的机制，当我们处理完等级为0的堆后，就可以在CT中寻找已经被修改了的对象。从而有效的完成垃圾回收。</p>
<p>但，事无完美，一旦CT内存被大量的G2对象占满时，则上述机制运行无效。但绝大多数情况下，G2对象是稳定的。这样，也能够解释，大多数的.net书籍会那么介绍<strong>垃圾回收机制</strong>了。当然是否有更好的机制，那得看聪明的您了。</p>
<p>参考资料：</p>
<ul>
<li>《Professional C# 2008》Christian Nagel，Bill Evjen@  Wiley Publishing, Inc.</li>
<li>MSDN doc: <a class="downloadlink" href="http://shao.mingbo.de/wp-content/plugins/download-monitor/download.php?id=3" title=" downloaded 46 times" >Garbage Collector Basics and Performance Hints (46)</a></li>
</ul>
<h3  class="related_post_title">相关文章</h3><ul class="related_post"><li>2009年11月25日 -- <a href="http://shao.mingbo.de/2009/11/25/basical-knowledge-of-csharp/" title="cSharp编程基础的学习笔记">cSharp编程基础的学习笔记</a></li><li>2009年12月22日 -- <a href="http://shao.mingbo.de/2009/12/22/how-to-use-backgroundworker-in-csharp/" title="cSharp中BackgroundWorker的用法">cSharp中BackgroundWorker的用法</a></li><li>2009年12月21日 -- <a href="http://shao.mingbo.de/2009/12/21/synchronize-class-design-in-csharp/" title="cSharp中同步类的设计">cSharp中同步类的设计</a></li><li>2009年12月20日 -- <a href="http://shao.mingbo.de/2009/12/20/paralize-thread-in-charp/" title="cSharp中给线程传递参数">cSharp中给线程传递参数</a></li><li>2009年12月19日 -- <a href="http://shao.mingbo.de/2009/12/19/asynchronous-delegate-in-csharp/" title="cSharp中异步委托的笔记">cSharp中异步委托的笔记</a></li></ul>]]></content:encoded>
			<wfw:commentRss>http://shao.mingbo.de/2009/11/23/dot-net-garbage-collector-analysis/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>
