马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有帐号?立即注册
x
另外,小型软件代码重用价值低,没有必要跨平台;大型软件,有严格的规划、部署,不可以随意跨平台。.NET开辟过程当中不是程式的没法运转,就是程式的效力慢的同蜗牛在爬;这类情形在.NET的老手中特别罕见;我不晓得为何,一些先容.NET开辟的书籍里援用的例子代码,也对此成绩置若罔闻,特别让我忧郁的是一些我喜好的书也呈现了一样的成绩。这篇文章不但对.NET开辟者的老手有匡助,一样对哪些有履历,也带来一些启发和参考。
他们会碰到甚么样的成绩?
1.数据库毗连超时
2.创立的工具尽管用,不论开释
3.调试(Debug)形式下编译后,就用于使用情况中了
4.实践功课形式分享
下面的成绩就像毒瘤,堆集到必定水平就发作,且影响深远。
1.数据库毗连超时篇
若要晓得数据库毗连超时成绩,先看上面一段代码:
[sample-01]
以下为援用的内容:
PublicSharedFunctiongetOEMPN(ByValpsPNAsString,ByRefOEMPNAsString)AsBSResult
DimclsResultAsNewBSResult
Try
clsResult.ResultID=-1
DimdtResultAsNewDataTable
DimSqlAsString=String.Empty
DimclsOraDbAsNewclsOraClienDb
DimstrConnAsString=ConfigurationManager.ConnectionStrings("ConnectionString").ConnectionString
clsOraDb.Open(strConn)‘这里Open后,前面看不到clsOraDb.Close
Sql="SELECTSATBMMBRND.OEMPNFRUNOFROMSATBMMBRNDWHERESATBMMBRND.MATNO=:MATNO"
Dimparams()AsracleParameter={NewOracleParameter("MATNO",psPN)}
IfclsOraDb.FillDataTable(Sql,dtResult,params)=FalseThen
ReturnclsResult
EndIf
IfdtResultIsNothingThen
ReturnclsResult
EndIf
IfdtResult.Rows.Count>0Then
OEMPN=dtResult.Rows(0)("FRUNO").ToString()
Else
OEMPN=""
EndIf
clsResult.ResultID=1
ReturnclsResult
CatchexAsException
clsResult.ResultID=-1
ReturnclsResult
EndTry
EndFunction
对上述代码行的部分化释:
DimclsOraDbAsNewclsOraClienDb:援用数据库毗连的类;
clsOraDb.Open(strConn):翻开数据库毗连;
然后,全部函数你再找不到封闭数据库毗连的举措,是要等着操纵体系来开释吗?有人就说啦,看起来仿佛没有甚么年夜不了的,这仅仅是一个函数罢了;数据库翻开毗连,未封闭不会影响到全部使用程式;果然是如许吗?
让我们谈谈数据库毗连的成绩,在Oracle数据库里,一样平常默许的数据库毗连数最多也就100多来个,不会凌驾200个,即便你改动这个毗连数;但不管如何,它的毗连数是无限的;不成能无穷地供你损耗。
在Web这个程式里,它不但不会主动封闭数据库毗连,象如许的函数还会每次挪用,城市从头用失落一个数据库毗连;假如象如许的函数良多的话,你就等着一个毛病告诫页面弹出来,如DatabaseConnectionTimeout…等讯息。
这还不算甚么,更有甚者,尽然在轮回语句里写上面的代码如:
[sample-02]
以下为援用的内容:- Foreach(DataRowrowintabl.select(“”,”ProductID”)……………clsOraDb.Open(strConn)………….Next有人还喜好玩上面的语句:[sample-03]Foreach(DataRowrowintabl.select(“”,”ProductID”)Foreach(DataColumncolintbl.columns)……………clsOraDb.Open(strConn)Next………….Next
复制代码 说到这,有人就问啦;我在开辟情况下测试一点成绩都没有呀?是呀,你是没有成绩;我想问的是,你开辟情况的测试数占有几笔?
如今,成绩已晓得在那里,怎样办理?
针对[sample-01]做以下处置,注重上面代码:
以下为援用的内容:- PublicSharedFunctiongetOEMPN(ByValpsPNAsString,ByRefOEMPNAsString)AsBSResultDimclsResultAsNewBSResultTryclsResult.ResultID=-1DimdtResultAsNewDataTableDimSqlAsString=String.EmptyDimclsOraDbAsNewclsOraClienDbDimstrConnAsString=
复制代码- ConfigurationManager.ConnectionStrings("ConnectionString").ConnectionStringclsOraDb.Open(strConn)正文:这里Open后,前面看不到clsOraDb.CloseSql="SELECTSATBMMBRND.OEMPNFRUNOFROMSATBMMBRNDWHERESATBMMBRND.MATNO=:MATNO"Dimparams()AsracleParameter={NewOracleParameter("MATNO",psPN)}IfclsOraDb.FillDataTable(Sql,dtResult,params)=FalseThenReturnclsResultEndIfIfdtResultIsNothingThenReturnclsResultEndIfIfdtResult.Rows.Count>0ThenOEMPN=dtResult.Rows(0)("FRUNO").ToString()ElseOEMPN=""EndIfclsResult.ResultID=1clsOraDb.Close正文:前面看到clsOraDb.CloseReturnclsResultCatchexAsExceptionclsOraDb.Close正文:程序非常也看到clsOraDb.CloseclsResult.ResultID=-1ReturnclsResultThrowexEndTryEndFunction
复制代码注重下面的两句代码:clsOraDb.Close和clsOraDb.Close;
在非常处置的时分,出格提示两点:
(1)你的数据库封闭的时分应当是在代码行0028前,而不是后;
(2)有人不习气(大概一时忽略)加上0088行的代码;
针对[Sample-02]和[sample-03],把翻开数据库毗连写在一切的轮回语句之前,如:
以下为援用的内容:- clsOraDb.Open(strConn)Foreach(DataRowrowintabl.select(“”,”ProductID”)……………………….Next
复制代码
固然另有别的一个做法,就是用Using语句,提交.NET使用的渣滓搜集器主动搜集;相干的文章良多;这里不再出格赘述。
2.工具尽管创立使用,不论开释篇
我们持续用[Sample-01]的代码:
DimdtResultAsNewDataTable
谁会发明它被开释,你不克不及,我也不克不及,历来没有被开释过。
“DimdtResultAsNewDataTable”行的代码注释是,要在内存分别一个空间给这个界说的工具dtresult;体系要分别多年夜的空间呢?呀,我没有研讨过(留给那些故意人吧,呵呵。.);但有一点,要在内存分别一个空间,就是要占用内存;那末内存有多年夜呢,不是无穷年夜吧;也是无限的;一切运转上述代码的终极了局是,体系的实行效力愈来愈慢;有人就嫌疑,我有内存1到2G的,加上假造内存就更年夜;我只能说你的嫌疑没错;但是你的使用程序就用这么一只函数吗?我想一定不是;以是上百只函数的使用实行对内存的损耗不可思议;假如是背景主动运转的程序,实时是一个function,也会让体系溃散;这只是一个复杂的例子,有更庞大的;象如许的工具使用另有:Dataset,Datatable,DataReader,DataAdapter,Datagrid.。等;
那末怎样办理这些成绩呢?
(1)在Trycatch语句前界说好所用的工具;如:
以下为援用的内容:
DimdtResultAsNewDataTable
DimDRasNewDataReader
DimDSasNewDataset
Try
..
CatchexAsException
(2)开释的语句以下:
以下为援用的内容:
DimdtResultAsNewDataTable
DimDRasNewDataReader
DimDSasNewDataset
Try
..
……………..
CatchexAsException
--开释使用的工具
Throwex
Finally
--利用完后,开释使用的工具
dtResult.dispose--从内存里分明该
有人习气写成上面如许:
以下为援用的内容:
DimdtResultAsNewDataTable
DimDRasNewDataReader
DimDSasNewDataset
Try
..
‘利用完后,开释使用的工具
dtResult.dispose‘从内存里分明该工具
DR.dispose‘从内存里分明该工具
DS.dispose‘从内存里分明该工具
CatchexAsException
这不是也开释了吗?我想问的是,假如程序呈现非常,它们会开释吗?我一定得告知人人,它们必定不克不及开释。为了确保程序的不乱运转,我倡议人人都来用TryCatch语句。
(3)毫不倡议在轮回语句写以下的语句:
以下为援用的内容:
Foreach(DataRowrowintabl.select(“”,”ProductID”)
……………
DimDSnewDataset记着此乃写代码之年夜忌;
DimDTnewDatabable….
………….
Next
另有一种写法
DimDSnewDataset
DimDTnewDatabable…
Foreach(DataRowrowintabl.select(“”,”ProductID”)
准确的写法是:
以下为援用的内容:
DimDSnewDataset
DimDTnewDatabable…
Try
Foreach(DataRowrowintabl.select(“”,”ProductID”)
DS=nothing‘每次利用,都先把内存空间开释出来
DT=nothing‘每次利用,都先把内存空间开释出来
DS=GetDatase
DT=GetDatatable……………
.
………….
Next
CatchexAsException
Throwex
Finally
DS.dispose
DT.dispose
EndTry
别的,提示人人一点,记得用ForEach语句替换Fori=0toRowcount-1;如许的效力改良也是分明的;
3.调试(Debug)形式下编译就用于使用情况中篇
人人看上面的图片:
有人会寄望这个界面吗?有,但必定未几。
接着,程式开辟好(也包含单位测试),然后编译间接分发到使用情况。
全部历程就停止了;谁也未曾想,这里埋下了一个深深的地雷;据微软的人讲,如许分发的程式到使用情况,你有几内存生怕都不敷,以是微软倡议我们做以下的事情:
“Web.config中的debug及Trace均OFalse。有您的一切程式_保compileReleaseMode
Applicationsetupfordebugging
OnereasonforhighmemorythatweseehereinSupportalotiswhenyouhavedebugging,tracing,orbothenabledforyourapplication.
Whileyouaredevelopingyourapplication,thisisanecessity.Bydefault,whenyoucreateyourapplicationinVisualStudio.NET,youwillseethefollowingattributesetinyourWeb.configfile:
and/or
Also,whenyoudoafinalbuildofyourapplication,makesurethatyoudothisin“Release”mode,not“Debug”mode.”
假如不如许做会有甚么事变产生?我分享一个同事的感觉给人人:“已是很刁悍的的DB和AP服务器(全体是刀片式服务器)了,但是成绩一而再再而三地产生,那种感到真的很无助很悲凉啊~”
厥后的了局发明是内存利用率超高,到必定限制的时分,就会反响变慢,这个时分只需重启IIS就能够好一段工夫;厥后剖析IIS用到实体加假造的内存凌驾2G就会爆失落;
这就是缘故原由,你想碰到吗?那就无妨尝尝。
4.实践操纵分享篇
下面三个环节,任何一个产生成绩,城市影响到体系的效力;我分享我们实践的功课的历程产生的一些情形,及怎样办理这些成绩。
(1)内存利用到达峰值,招致程序没法持续运转;
有个同事分享了他们的履历以下(原话分享):
我们有一些程式是server跑的Job,并有愈来愈多之势。而人人在写程式的时分大概对照少思索到耗内存这个成绩。
上面的例子大概会给我们一点启发。
上面也是原话:
PlshelptochecktheRunInRackJobprogram.Itwillnoresponseafterrunningtwoorthreedays.theAPserverMemoryusagewillover2.5G.afterweclosethetheprogram,Memorywilldecreaseto1.5.
大抵意义是:在服务器端(也叫背景)主动跑的一只程式,运转了两三天后,中断运转了;
反省Server的内存利用率时,发明凌驾了2.5G;在关失落了这只程式后,它就降到了1.5G…上面的图片为证:
(2)历程哀求过量,招致CPU没法实时处置,程序效力反响较慢。
上面都是同事的原话:
“年后产量渐渐增添,新的成绩又呈现了。从ServerPerformance上剖析,和前次Memory太高分歧的是CPU利用率太高。每当CPU太高的时分,产线会年夜面积的反响说慢(这点和毗连到哪台AP有干系)。每次慢的时分,我们就找到CPU太高的那台AP,recycleIIS的applicationpool后就OK了。因而我么再次找到Bon协助剖析(结论:微软了案呈报20090226V1-SRT090119833891Webservicecan‘tserveIISResetcanfix.msg)。并给出了开辟程序时的一些倡议。
结论大抵是说,没有历程占用了出格高的CPU,也没有历程占用CPU工夫太长。只是对DB的哀求的历程过量(对照符合3厂的实践情况—附件多,刷的快),加起来就全体太高。还发明了良多DLL是builtindebugmode,这些DLL占用了过量的memory资本。厥后依据Bon的倡议,我们修正了IISapplicationpool的设定以下,办理过量哀求不克不及实时处置,而形成CPU太高的成绩。”
这里有一些问答关于使用毗连池(ApplicationPool)的设定,对了解如许的设置有必定的匡助:
1.Isoneapplicationpool’smaximummemoryusage1.5G?
A&:Eachapplicationpoolisaw3wp.exe.w3wp.exeisaprocess.Everyprocesshas2GUsermodevirtualaddress,sothemaximummemoryusageforapplicationpoolis2G.However,youcan’tmakesurethatthereisnomemoryfragmentissue.Therefore,Outofmemoryalwaysoccurafter1.5Gaccordingtoourexperience.
2.Iseachapplicationpoolindependentonmemoryusage?
A&:Differentapplicationpoolsaredifferentw3wp.exe,soeachapplicationpool’smaximummemoryusageis2G.
3.CansetupmaximumCPUusageoneachapplicationpool?
A&:Youcanmonitorit,butyoucan’tsetupit.
2003年中微软发布最新版本的ASP.netWebMatrix,对于我们喜欢用Asp.net来编程的朋友实在是个好消息,我也实实在在的将Asp.net更深入的研究了一下,以方便我以后更好的运用它,同时我也讲讲使用它的感受。 |