问题描述
写了一个程序,CPU老是飙到100%,但是又不知道那个地方写法有问题,本地测试一点问题都没有,放在服务器上,开始也没有问题,就是一段时间之后CPU就升上去了,有的时候只有40%到50%,有的时候居然100%,底层数据访问使用如下的SQLHelper辅助类来实现,所有查询都是调用ExecuteTable()函数,举个例子:没有分了,抱歉,都来看一下吧!stringsql="Pro_PageALL_new";SQLHelpersqlHelper=newSQLHelper();sqlHelper.AddInParameter("@TableName",SqlDbType.VarChar,200,tableName);sqlHelper.AddInParameter("@Fields",SqlDbType.VarChar,2000,fields);sqlHelper.AddInParameter("@WhereClause",SqlDbType.VarChar,2000,whereClause);sqlHelper.AddInParameter("@OrderBy",SqlDbType.VarChar,2000,orderBy);sqlHelper.AddInParameter("@PageIndex",SqlDbType.Int,pageIndex);sqlHelper.AddInParameter("@PageSize",SqlDbType.Int,pageSize);sqlHelper.AddOutParameter("@PageCount",SqlDbType.Int);sqlHelper.AddOutParameter("@RecordCount",SqlDbType.Int);DataTabledt=sqlHelper.ExecuteTable(sql);
publicclassSQLHelper{privatestring_connstr="";privateSqlCommand_cmd=null;privateSqlParameter_param=null;///<summary>///默认构造函数///</summary>publicSQLHelper(){_cmd=newSqlCommand();_cmd.CommandTimeout=300;_connstr=ConfigurationManager.ConnectionStrings["SQLConnString"].ConnectionString;_cmd.Connection=newSqlConnection(_connstr);}///<summary>///根据数据库链接标识实例化构造函数///</summary>///<paramname="connkey">数据库链接标识</param>publicSQLHelper(stringconnkey){_cmd=newSqlCommand();_cmd.CommandTimeout=300;_connstr=ConfigurationManager.ConnectionStrings[connkey].ConnectionString;_cmd.Connection=newSqlConnection(_connstr);}///<summary>///添加命令参数///</summary>///<paramname="name">名称</param>///<paramname="dbType">类型</param>///<paramname="direction">方向</param>publicvoidAddParameter(stringname,SqlDbTypedbType,ParameterDirectiondirection){_param=newSqlParameter(name,dbType);_param.Direction=direction;_cmd.Parameters.Add(_param);}///<summary>///添加命令参数///</summary>///<paramname="name">名称</param>///<paramname="dbType">数据类型</param>///<paramname="size">大小</param>///<paramname="direction">方向</param>publicvoidAddParameter(stringname,SqlDbTypedbType,intsize,ParameterDirectiondirection){_param=newSqlParameter(name,dbType,size);_param.Direction=direction;_cmd.Parameters.Add(_param);}///<summary>///添加命令参数///</summary>///<paramname="name">名称</param>///<paramname="dbType">数据类型</param>///<paramname="direction">方向</param>///<paramname="value">值</param>publicvoidAddParameter(stringname,SqlDbTypedbType,ParameterDirectiondirection,objectvalue){_param=newSqlParameter(name,dbType);_param.Direction=direction;_param.Value=value;_cmd.Parameters.Add(_param);}///<summary>///添加命令参数///</summary>///<paramname="name">名称</param>///<paramname="dbType">数据类型</param>///<paramname="size">大小</param>///<paramname="direction">方向</param>///<paramname="value">值</param>publicvoidAddParameter(stringname,SqlDbTypedbType,intsize,ParameterDirectiondirection,objectvalue){_param=newSqlParameter(name,dbType,size);_param.Direction=direction;_param.Value=value;_cmd.Parameters.Add(_param);}///<summary>///添加命令输入参数///</summary>///<paramname="name">名称</param>///<paramname="dbType">数据类型</param>///<paramname="value">值</param>publicvoidAddInParameter(stringname,SqlDbTypedbType,objectvalue){_param=newSqlParameter(name,dbType);_param.Direction=ParameterDirection.Input;_param.Value=value;_cmd.Parameters.Add(_param);}///<summary>///添加命令输入参数///</summary>///<paramname="name">名称</param>///<paramname="dbType">数据类型</param>///<paramname="size">大小</param>///<paramname="value">值</param>publicvoidAddInParameter(stringname,SqlDbTypedbType,intsize,objectvalue){_param=newSqlParameter(name,dbType,size);_param.Direction=ParameterDirection.Input;_param.Value=value;_cmd.Parameters.Add(_param);}///<summary>///添加命令输出参数///</summary>///<paramname="name">名称</param>///<paramname="dbType">数据类型</param>publicvoidAddOutParameter(stringname,SqlDbTypedbType){_param=newSqlParameter(name,dbType);_param.Direction=ParameterDirection.Output;_cmd.Parameters.Add(_param);}///<summary>///添加命令输出参数///</summary>///<paramname="name">名称</param>///<paramname="dbType">数据类型</param>///<paramname="size">大小</param>publicvoidAddOutParameter(stringname,SqlDbTypedbType,intsize){_param=newSqlParameter(name,dbType,size);_param.Direction=ParameterDirection.Output;_cmd.Parameters.Add(_param);}///<summary>///获取输出类型命令参数的值///</summary>///<paramname="ParamName"></param>///<returns></returns>publicobjectGetOutParameterValue(stringname){return_cmd.Parameters[name].Value;}///<summary>///清空命令参数///</summary>publicvoidClearParameters(){_cmd.Parameters.Clear();}///<summary>///增删改的公共方法///</summary>///<paramname="commandText">Sql语句火存储过程名称</param>///<paramname="prms">参数集合</param>///<returns>影响行数</returns>publicintExecuteNonQuery(stringcommandText){_cmd.CommandType=CommandType.StoredProcedure;_cmd.CommandText=commandText;try{_cmd.Connection.Open();return_cmd.ExecuteNonQuery();}catch(SqlException){throw;}catch(Exception){throw;}finally{if(_cmd.Connection!=null&&_cmd.Connection.State!=ConnectionState.Closed){_cmd.Connection.Close();}}}///<summary>///增删改的公共方法///</summary>///<paramname="commandType">Sql语句类型</param>///<paramname="commandText">Sql语句火存储过程名称</param>///<paramname="prms">参数集合</param>///<returns>影响行数</returns>publicintExecuteNonQuery(CommandTypecommandType,stringcommandText){_cmd.CommandType=commandType;_cmd.CommandText=commandText;try{_cmd.Connection.Open();return_cmd.ExecuteNonQuery();}catch(SqlException){throw;}catch(Exception){throw;}finally{if(_cmd.Connection!=null&&_cmd.Connection.State!=ConnectionState.Closed){_cmd.Connection.Close();}}}
解决方案
解决方案二:
///<summary>///返回查询结果的第一行第一列///</summary>///<paramname="commandText">Sql语句火存储过程名称</param>///<paramname="prms">参数集合</param>///<returns>第一行第一列</returns>publicObjectExecuteScalar(stringcommandText){_cmd.CommandType=CommandType.StoredProcedure;_cmd.CommandText=commandText;try{_cmd.Connection.Open();return_cmd.ExecuteScalar();}catch(SqlException){throw;}catch(Exception){throw;}finally{if(_cmd.Connection!=null&&_cmd.Connection.State!=ConnectionState.Closed){_cmd.Connection.Close();}}}///<summary>///返回查询结果的第一行第一列///</summary>///<paramname="commandType">Sql语句类型</param>///<paramname="commandText">Sql语句火存储过程名称</param>///<paramname="prms">参数集合</param>///<returns>第一行第一列</returns>publicObjectExecuteScalar(CommandTypecommandType,stringcommandText){_cmd.CommandType=commandType;_cmd.CommandText=commandText;try{_cmd.Connection.Open();return_cmd.ExecuteScalar();}catch(SqlException){throw;}catch(Exception){throw;}finally{if(_cmd.Connection!=null&&_cmd.Connection.State!=ConnectionState.Closed){_cmd.Connection.Close();}}}///<summary>///查询集合///</summary>///<paramname="commandText">Sql语句火存储过程名称</param>///<paramname="prms">参数集合</param>///<returns>SqlDataReader集合</returns>publicSqlDataReaderExecuteReader(stringcommandText){SqlDataReadersr=null;_cmd.CommandType=CommandType.StoredProcedure;_cmd.CommandText=commandText;try{_cmd.Connection.Open();sr=_cmd.ExecuteReader(CommandBehavior.CloseConnection);returnsr;}catch(SqlException){throw;}catch(Exception){throw;}}///<summary>///查询集合///</summary>///<paramname="commandText">Sql语句火存储过程名称</param>///<paramname="prms">参数集合</param>///<returns>Datatable</returns>publicDataTableExecuteTable(stringcommandText){DataTabledt=newDataTable();SqlDataAdaptersda=null;_cmd.CommandType=CommandType.StoredProcedure;_cmd.CommandText=commandText;try{_cmd.Connection.Open();sda=newSqlDataAdapter(_cmd);sda.Fill(dt);returndt;}catch(SqlException){throw;}catch(Exception){throw;}finally{if(_cmd.Connection!=null&&_cmd.Connection.State!=ConnectionState.Closed){_cmd.Connection.Close();}}}///<summary>///查询集合///</summary>///<paramname="commandType">Sql语句类型</param>///<paramname="commandText">Sql语句火存储过程名称</param>///<paramname="prms">参数集合</param>///<returns>SqlDataReader集合</returns>publicSqlDataReaderExecuteReader(CommandTypecommandType,stringcommandText){SqlDataReadersr=null;_cmd.CommandType=commandType;_cmd.CommandText=commandText;try{_cmd.Connection.Open();sr=_cmd.ExecuteReader(CommandBehavior.CloseConnection);returnsr;}catch(SqlException){throw;}catch(Exception){throw;}}///<summary>///查询集合///</summary>///<paramname="commandType">Sql语句类型</param>///<paramname="commandText">Sql语句火存储过程名称</param>///<paramname="prms">参数集合</param>///<returns>Datatable</returns>publicDataTableExecuteTable(CommandTypecommandType,stringcommandText){DataTabledt=newDataTable();SqlDataAdaptersda=null;_cmd.CommandType=commandType;_cmd.CommandText=commandText;try{_cmd.Connection.Open();sda=newSqlDataAdapter(_cmd);sda.Fill(dt);returndt;}catch(SqlException){throw;}catch(Exception){throw;}finally{if(_cmd.Connection!=null&&_cmd.Connection.State!=ConnectionState.Closed){_cmd.Connection.Close();}}}}
解决方案三:
cpu应该与dbhelp没关系把内存与dbhelp有关系你不释放资源内存就漫了
解决方案四:
真狠,把这么多都粘上来了,从上面拖到最下面都晕了,更不用说看了。。。
解决方案五:
CPU高要先确认是哪个程序,在程序里要看主要的循环部分。你的代码可是一点关系都没有。
解决方案六:
这里有点小问题,private SqlCommand _cmd = null;privateSqlParameter_param=null;你既然在类中维护这种继承IDisposable的非托管的对象,那么在你这个SQLHelper类中就应该实现IDisposable。应该实现手动Dispose()释放非托管资源,同时最好再实现~SQLHelper()析构函数来实现垃圾回收时自动释放非托管资源。具体可以参考非托管资源的释放。
解决方案七:
CPU100%跟你这段代码没关系~~
解决方案八:
引用5楼minhua1983的回复:
这里有点小问题,private SqlCommand _cmd = null;privateSqlParameter_param=null;你既然在类中维护这种继承IDisposable的非托管的对象,那么在你这个SQLHelper类中就应该实现IDisposable。应该实现手动Dispose()释放非托管资源,同时最好再实现~SQLHelper()析构函数来实现垃圾回收时自动释放非托管资源。具体可以参考非托管资源的释放。
你的意思是不是这样:想DataReader和SqlConnection这样的对象都需要Dispose()释放资源?
解决方案九:
不晓得楼主以何为依据判断瓶颈是在sqlhelper??
解决方案十:
不知道楼主以何为依据判断问题就是在sqlhelper!!
解决方案十一:
调用的DataReader没有关闭吧
解决方案十二:
引用9楼shiyong7682719的回复:
不知道楼主以何为依据判断问题就是在sqlhelper!!
有死锁的情况发生,发生在查询分页数据的时候,之前好像在网上看过微软petshop的SqlHelper的函数使用抽象类的形式,调用静态方法好像不会发生死锁。所以怀疑自己写法有问题。
解决方案十三:
引用7楼YourBer的回复:
Quote: 引用5楼minhua1983的回复:
这里有点小问题,private SqlCommand _cmd = null;privateSqlParameter_param=null;你既然在类中维护这种继承IDisposable的非托管的对象,那么在你这个SQLHelper类中就应该实现IDisposable。应该实现手动Dispose()释放非托管资源,同时最好再实现~SQLHelper()析构函数来实现垃圾回收时自动释放非托管资源。具体可以参考非托管资源的释放。你的意思是不是这样:想DataReader和SqlConnection这样的对象都需要Dispose()释放资源?
我的意思是你的SQLHelper._cmd和SQLHelper._param属于SQLHelper的字段,而不是在SQLHelper的某个方法中定义的,如果定义在某个方法里面,就不用实现IDispose接口,即便在某个方法中定义的话,也最好使用using来写,这样当超出using语句块,会自动调用_cmd.Dispose()或_param.Dispose()的。而你SQLHelper的这种写法(SQLHelper._cmd和SQLHelper._param属于SQLHelper的字段)就应该实现IDispose接口。以前我也不知道应该这样写,但是我看了非托管资源的释放之后才知道的。不过我不确认这个是否就是引起你100%CPU的原因。
解决方案十四:
引用11楼YourBer的回复:
Quote: 引用9楼shiyong7682719的回复:
不知道楼主以何为依据判断问题就是在sqlhelper!!有死锁的情况发生,发生在查询分页数据的时候,之前好像在网上看过微软petshop的SqlHelper的函数使用抽象类的形式,调用静态方法好像不会发生死锁。所以怀疑自己写法有问题。
如果楼主想确认是否是由sqlhelper引起的,那很好办,你把你的SQLHelper换成静态的即可,然后测试下就知道原因了。
解决方案十五:
把底层数据访问层换成微软的petshop那种,CPU依然飙到了100%,最后查看日志发现只有一个异常——“死锁”,而死锁发生在查询分页数据的时候,现在做的操作是在分页查询语句后面加上WITH(NOLOCK),还在测试,先测几天看看。
解决方案:
调用的DataReader没有用using
解决方案:
是写SQL语句的问题跟这东西没关系
解决方案:
引用14楼YourBer的回复:
把底层数据访问层换成微软的petshop那种,CPU依然飙到了100%,最后查看日志发现只有一个异常——“死锁”,而死锁发生在查询分页数据的时候,现在做的操作是在分页查询语句后面加上WITH(NOLOCK),还在测试,先测几天看看。
分页这会也不死锁了,CPU依然飙到100%,无语了,看日志有一个异常:HttpExceptionExceptionmessage:ApotentiallydangerousRequest.Pathvaluewasdetectedfromtheclient(?).然后百度了一下,好像是有特殊字符才会出现这个异常,但是访问出错的路径,都正常访问,也没有特殊字符,我就是想知道,什么原因会导致CPU上升呢?