仓酷云

标题: NET网页编程之深切懂得.net渣滓接纳机制之代龄与算法详解 [打印本页]

作者: 飘灵儿    时间: 2015-1-16 14:21
标题: NET网页编程之深切懂得.net渣滓接纳机制之代龄与算法详解
因为各系统的API不同,代码调用API编写程序就会遇到很多不兼容的地方,比如Java改写后的Serv-U就不能在手机上执行,手机的游戏也不能直接在微机上执行。1、代龄(Generation)


  代龄就是对Heap中的工具依照存在工夫是非举行分代,最短的分在第0代,最长的分在第2代,第2代中的工具常常是对照年夜的。Generation的层级与FrameWork版本有关,能够经由过程挪用GC.MaxGeneration得知。

  一般,GC会优先搜集那些比来分派的工具(第0代),这与操纵体系典范内存换页算法“比来起码利用”算法一模一样。可是,这其实不代表GC只搜集比来分派的工具,一般,.NetGC将堆空间按工具的保存期是非分红3代:新分派的工具在第0代(0代空间最年夜长度一般为256K),按地点按次分派,它们一般是一些部分变量;第1代(1代空间最年夜长度一般为2MB)是经由0代渣滓搜集后仍旧驻留在内存中的工具,它们一般是一些如表单,按钮等工具;第2代是履历过几回渣滓搜集后仍旧驻留在内存中的工具,它们一般是一些使用程序工具。

  当内存吃紧时(比方0代工具充斥),GC便被调进实行引擎——也就是CLR——入手下手对第0代的空间举行标志与紧缩事情、接纳事情,这一般小于1毫秒。假如接纳后内存仍然吃紧,那末GC会持续接纳第1代(接纳操纵一般小于10毫秒)、第2代,固然GC偶然并非依照第0、1、2代的按次搜集渣滓的,这取决于运转时的情形,或是手动挪用GC.Collect(i)指定接纳的代。当对第2代接纳前任然没法取得充足的内存,那末体系就会抛出OutOfMemoryException非常

  当经由几回GC事后,0代中的某个工具仍旧存在,那末它将被挪动到第1代。同理,第1、2代也按一样的逻辑运转。

  这里还要说的是,GCHeap中代的数目与容量,都是可变的(这由一个“战略引擎”把持,在第二节中,会先容到“战略引擎”),以下代码分离Windbg能够申明这个成绩,以下代码中,能够经由过程单击按钮“button1”,不休的分派内存,尔后取得工具“a”的代龄情形,而且在Form加载时也会取得“a”的代龄。

请看源码示例:
publicpartialclassForm1:Form
{
privatestringa=newstring(a,1);
publicForm1()
{
InitializeComponent();
}
privatevoidbutton1_Click(objectsender,EventArgse)
{
a=newstring(a,900000);
label1.Text=GC.GetGeneration(a).ToString();
}
privatevoidForm1_Load(objectsender,EventArgse)
{
label1.Text=GC.GetGeneration(a).ToString();
}
}

程序刚加载时,“a”的代龄为第0代,经由过程windbg我们能够取得以下信息:
NET网页编程之深切懂得.net渣滓接纳机制之代龄与算法详解
登录/注册后可看大图


能够看出,GC堆被分红了两个段,三代,每代肇端地点十进制差值为12。
点击数次“button1”按钮后,“a”的代龄升为第2代,经由过程windbg我们又取得了以下信息:
NET网页编程之深切懂得.net渣滓接纳机制之代龄与算法详解
登录/注册后可看大图


这里要注重一个很关头的中央,就是各代的肇端(generationxstartsat)十进制地点差值不再是12,0代与1代差为98904,1代与2代差为107908,这申明代的巨细随程序运转在改动,而且GCheap的巨细也有变更。

2、算法


渣滓搜集器的实质,就是跟踪一切被援用到的工具,收拾工具不再被援用的工具,接纳响应的内存。

 这听起来相似于一种叫做“援用计数(ReferenceCounting)”的算法,但是这类算法必要遍历一切工具,并保护它们的援用情形,以是效力较低些,而且在呈现“环援用”时很简单形成内存保守。以是.Net中接纳了一种叫做“标志与扫除(MarkSweep)”算法来完成上述义务。

“扫除”--接纳内存:启用Compact算法,对内存中存活的工具举行挪动,修正它们的指针,使之在内存中一连,如许余暇的内存也就一连了,这就办理了内存碎片成绩,当再次为新工具分派内存时,CLR不用在充斥碎片的内存中寻觅合适新工具的内存空间,以是分派速率会年夜年夜进步。可是年夜工具(largeobjectheap)除外,GC不会挪动一个内存中巨无霸,由于它晓得如今的CPU方便宜。一般,年夜工具具有很长的保存期,当一个年夜工具在.NET托管堆中发生时,它被分派在堆的一个特别部分中,挪动年夜工具所带来的开支凌驾了收拾这部分堆所能进步的功能。

  Compact算法除会进步再次分派内存的速率,假如新分派的工具在堆中地位很松散的话,高速缓存的功能将会失掉进步,由于一同分派的工具常常被一同利用(程序的部分性道理),以是为程序供应一段一连空缺的内存空间是很主要的。

“标志”--渣滓的辨认
从使用程序的root动身,使用互相援用干系,遍历其在Heap上静态分派的一切工具,没有被援用的工具不被标志,即成为渣滓;存活的工具被标志,即保护成了一张“根-工具可达图”。

  实在,CLR会把工具干系看作“树图”,无疑,懂得数据布局的同砚都晓得,有了“树图”的观点,会加速遍历工具的速率。

  检测、标志工具援用,是一件很成心思的事变,有良多办法能够做到,可是只要一种是效力最优的,.Net中是使用栈来完成的,在不休的进栈与出栈中完成检测:先在树图当选择一个必要检测的工具,将该工具的一切援用压栈,云云重复直到栈变空为止。栈变空意味着已遍历了这个部分根(大概说是树图中的节点)可以抵达的一切工具。树图节点局限包含部分变量(实践上部分变量会很快被接纳,由于它的感化域很分明、很好把持)、存放器、静态变量,这些元素都要反复这个操纵。一旦完成,便逐一工具地反省内存,没有标志的工具酿成了渣滓。其实Java之所以在曾经独步天下,就是因为他的跨平台、安全性,这两方面,效率可不是Java的强项,反而是他最短的一块挡板,虽然net总是用理论证明比.NET快。
作者: 小女巫    时间: 2015-1-18 13:28
碰到复杂点的问题都不知道能不能解决,现在有点实力的公司都选择自已在开源的基础上做开发。但没听说过有人在IIS上做改进的,windows、sqlserver集群方面的应用也很少见。
作者: 山那边是海    时间: 2015-1-24 09:41
ASP在执行的时候,是由IIS调用程序引擎,解释执行嵌在HTML中的ASP代码,最终将结果和原来的HTML一同送往客户端。
作者: 柔情似水    时间: 2015-2-1 07:17
代码的可重用性差:由于是面向结构的编程方式,并且混合html,所以可能页面原型修改一点,整个程序都需要修改,更别提代码重用了。
作者: 灵魂腐蚀    时间: 2015-2-7 02:05
以上是语言本身的弱点,在功能方面ASP同样存在问题,第一是功能太弱,一些底层操作只能通过组件来完成,在这点上是远远比不上PHP/JSP,其次就是缺乏完善的纠错/调试功能,这点上ASP/PHP/JSP差不多。
作者: 再现理想    时间: 2015-2-19 21:08
由于CGI程序每响应一个客户就会打开一个新的进程,所以,当有多个用户同时进行CGI请求的时候,服务器就会打开多个进程,这样就加重了服务器的负担,使服务器的执行效率变得越来越低下。
作者: 愤怒的大鸟    时间: 2015-3-6 16:00
目前在微软的.net战略中新推出的ASP.net借鉴了Java技术的优点,使用CSharp(C#)语言作为ASP.net的推荐语言,同时改进了以前ASP的安全性差等缺点。但是,使用ASP/ASP.net仍有一定的局限性,因为从某种角度来说它们只能在微软的WindowsNT/2000/XP+IIS的服务器平台上良好运行(虽然像ChilliSoft提供了在UNIX/Linux上运行ASP的解决方案.
作者: 若天明    时间: 2015-3-13 04:45
由于CGI程序每响应一个客户就会打开一个新的进程,所以,当有多个用户同时进行CGI请求的时候,服务器就会打开多个进程,这样就加重了服务器的负担,使服务器的执行效率变得越来越低下。
作者: 爱飞    时间: 2015-3-20 13:18
那么,ASP.Net有哪些改进呢?




欢迎光临 仓酷云 (http://ckuyun.com/) Powered by Discuz! X3.2