.NET开发过程中不是程式的无法运行,就是程式的效率慢的同蜗牛在爬; 这种情况在.NET的新手中尤其常见;我不知道为什么,一些介绍.NET开发的书本里引用的例子代码,也对此问题视而不见,尤其让我郁闷的是一些我喜欢的书也出现了同样的问题。 这篇文章不仅对.NET开发者的新手有帮助,同样对哪些有经验,也带来一些启示和参考。 他们会遇到什么样的问题? 1. 数据库连接超时 2. 创建的对象只管用,不管释放 3. 调试(Debug)模式下编译后,就用于应用环境中了 4. 实际作业模式分享 上面的问题就像毒瘤,积累到一定程度就爆发,且影响深远。 1.数据库连接超时篇 若要知道数据库连接超时问题,先看下面一段代码: [sample-01]
对上述代码行的部分解释: Dim clsOraDb As New clsOraClienDb:引用数据库连接的类; clsOraDb.Open(strConn):打开数据库连接; 然后,整个函数你再找不到关闭数据库连接的动作,是要等着操作系统来释放吗? 有人就说啦,看起来好像没有什么大不了的,这仅仅是一个函数而已;数据库打开连接,未关闭不会影响到整个应用程式;果真是这样吗? 让我们谈谈数据库连接的问题,在Oracle数据库里,一般默认的数据库连接数最多也就100多来个,不会超过200个,即使你改变这个连接数;但无论怎样,它的连接数是有限的;不可能无限地供你消耗。 在Web这个程式里,它不仅不会自动关闭数据库连接,象这样的函数还会每次调用,都会重新用掉一个数据库连接;如果象这样的函数很多的话,你就等着一个错误警告页面弹出来,如Database Connection Timeout…等讯息。 这还不算什么,更有甚者,尽然在循环语句里写下面的代码如 : [sample-02]
说到这,有人就问啦;我在开发环境下测试一点问题都没有呀?是呀,你是没有问题;我想问的是,你开发环境的测试数据有几笔? 现在,问题已经知道在哪里,怎么解决? 针对[sample-01]做如下处理,注意下面代码:
注意上面的两句代码:clsOraDb.Close和clsOraDb.Close; 在异常处理的时候,特别提醒两点: (1)你的数据库关闭的时候应该是在代码行0028前,而不是后; (2)有人不习惯(或者一时疏忽)加上0088行的代码; 针对[Sample-02]和[sample-03],把打开数据库连接写在所有的循环语句之前,如:
当然还有另外一个做法,就是用Using语句,提交.NET应用的垃圾收集器自动收集;相关的文章很多;这里不再特别赘述。 2.对象只管创建应用,不管释放篇 我们继续用[Sample-01]的代码: Dim dtResult As New DataTable 谁会发现它被释放,你不能,我也不能,从来没有被释放过。 “Dim dtResult As New DataTable”行的代码解释是,要在内存划分一个空间给这个定义的对象dtresult;系统要划分多大的空间呢?呀,我没有研究过(留给那些有心人吧,呵呵。.);但有一点,要在内存划分一个空间,就是要占用内存;那么内存有多大呢,不是无限大吧;也是有限的;所有运行上述代码的最终结果是,系统的执行效率越来越慢;有人就怀疑,我有内存1到2G的,加上虚拟内存就更大;我只能说你的怀疑没错;可是你的应用程序就用这么一只函数吗?我想肯定不是;所以上百只函数的应用执行对内存的消耗可想而知;如果是后台自动运行的程序,及时是一个function,也会让系统崩溃;这只是一个简单的例子,有更复杂的;象这样的对象应用还有:Dataset, Datatable,DataReader,DataAdapter,Datagrid.。等; 那么怎么解决这些问题呢? (1)在Try catch 语句前定义好所用的对象; 如:
(2)释放的语句如下:
有人习惯写成下面这样:
这不是也释放了吗?我想问的是,如果程序出现异常,它们会释放吗?我肯定得告诉大家,它们一定不能释放。为了确保程序的稳定运行,我建议大家都来用Try Catch语句。 (3)绝不建议在循环语句写如下的语句:
正确的写法是:
另外,提醒大家一点,记得用 For Each 语句替代For i=0 to Rowcount-1;这样的效率改善也是明显的; 3.调试(Debug)模式下编译就用于应用环境中篇 大家看下面的图片: 有人会留意这个界面吗?有,但一定不多。 接着,程式开发好(也包括单元测试),然后编译直接分发到应用环境。 整个过程就结束了;谁也不曾想,这里埋下了一个深深的地雷;据微软的人讲,这样分发的程式到应用环境,你有多少内存恐怕都不够,所以微软建议我们做如下的工作: “請將Web.config中的debug及Trace均設為False。還有您的所有程式請確保compile為Release Mode Application set up for debugging One reason for high memory that we see here in Support a lot is when you have debugging, tracing, or both enabled for your application. While you are developing your application, this is a necessity.By default, when you create your application in Visual Studio .NET, you will see the following attribute set in your Web.config file: and/or Also, when you do a final build of your application, make sure that you do this in “Release” mode, not “Debug” mode. ” 如果不这样做会有什么事情发生? 我分享一个同事的感受给大家:“已经是很强悍的的DB和AP服务器(全部是刀片式服务器)了,可是问题一而再再而三地发生,那种感觉真的很无助很凄凉啊~” 后来的结果发现是内存使用率超高,到一定限度的时候,就会反应变慢,这个时候只要重启IIS就可以好一段时间;后来分析IIS用到实体加虚拟的内存超过2G就会爆掉; 这就是原因,你想遇到吗?那就不妨试试。 4.实际操作分享篇 上面三个环节,任何一个发生问题,都会影响到系统的效率;我分享我们实际的作业的过程发生的一些情况,及怎么解决这些问题。 (1)内存使用达到峰值,导致程序无法继续运行; 有个同事分享了他们的经验如下(原话分享): 我们有一些程式是server跑的Job,并有越来越多之势。而大家在写程式的时候可能比较少考虑到耗内存这个问题。 下面的例子也许会给我们一点启示。 下面也是原话: Pls help to check the Run In Rack Job program . It will no response after running two or three days . the AP server Memory usage will over 2.5G . after we close the the program , Memory will decrease to 1.5 . 大致意思是:在服务器端(也叫后台)自动跑的一只程式,运行了两三天后,停止运行了; 检查Server的内存使用率时,发现超过了2.5G;在关掉了这只程式后,它就降到了1.5G…下面的图片为证: (2)进程请求过多,导致CPU无法及时处理,程序效率反应较慢。 下面都是同事的原话: “年后产量逐渐增加,新的问题又出现了。从Server Performance上分析,和上次Memory过高不同的是CPU使用率过高。每当CPU过高的时候,产线会大面积的反应说慢(这点和连接到哪台AP有关系)。每次慢的时候,我们就找到CPU过高的那台AP,recycle IIS的application pool后就OK了。于是我么再次找到Bon帮忙分析(结论:微软结案报告 20090226V1 - SRT090119833891 Web service can‘t serve IISReset can fix.msg)。并给出了开发程序时的一些建议。 结论大致是说,没有进程占用了特别高的CPU,也没有进程占用CPU时间过长。只是对DB的请求的进程过多(比较吻合3厂的实际状况—附件多,刷的快),加起来就整体过高。还发现了很多DLL是built in debug mode,这些DLL占用了过多的memory资源。后来根据Bon的建议,我们修改了IIS application pool的设定如下,解决过多请求不能及时处理,而造成CPU过高的问题。” 这里有一些问答关于应用连接池(Application Pool)的设定,对理解这样的设置有一定的帮助: 1. Is one application pool’s maximum memory usage 1.5G? 2. Is each application pool independent on memory usage? 3. Can setup maximum CPU usage on each application pool? | |||||||||