Welcome

首页 / 软件开发 / .NET编程技术 / 使用CLR会造成内存方面的问题吗

使用CLR会造成内存方面的问题吗2011-03-31 IT专家网 Peak Wong我老是担心使用CLR会造成内存方面的问题,比如内存不能回收。其实想一想也许我过滤了,毕竟.NET Framework能够自己回收托管内存。既然在应用服务器上能使用,数据库上似乎也可以使用。

希望听一听大家的经验和见解~~

Peak Wong:

一般不用, 主要是DBA管理这种东西的时候会很麻烦, 因为自己写的CLR很难保证没有BUG, 一旦出BUG, 如果只是影响调用那一部分还好, 如果导致整个服务挂掉, 则很危险了(而且往往导致服务器挂掉还不一定查得出来是否CLR的问题)

另外, 部署和迁移也是要考虑的问题之一。还有感觉 CLR 还没有想像中的那么稳定(或者是与 SQL SERVER 的配合没有想像中的好)

例如在处理 复制出错的时候, 有时会调用一些存储过程去查看出错相关的信息, 这些存储过程中的一部分就是 CLR 存储过程, 经常会发现怎么也调不成功, 说什么内存错误什么的, 但实际上空闲内存肯定是够的.

而且一般第一次调用CLR的时候, 加载程序集花费的时间也不短, 所以如果 CLR 用得多, 内存又不太够, 导致一些CLR程序集老是反复加载的话, 性能会非常低。

内存回收机制确实很智能,只不过只需要把比如打开文件啊,开数据库啊什么的关闭就可以了。就不会造成多余的系统开销。如果害怕的话,可以写段折构函数!以前学习的时候写过一个例子,但是用处不打,可以借鉴一下。

C# code

using System;
using System.IO;
using System.Windows.Forms;

namespace nameSpace1
{
public class gcDemo:IDisposable
{
static int ctor_cnt = 0;
static int dtor_cnt = 0;
static public gcDemo c1;
static public StreamWriter ofile;
static int iterations;
private bool isDispose = false;
public void Dispose()
{
Dispose(true);
System.GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing)
{
if(!isDispose)
{
if(disposing)
ofile.Close();
}
isDispose = true;
}
static public int Iterations
{
get
{
return iterations;
}
set
{
iterations = value;
}
}
static gcDemo()
{
string startupPath;
startupPath = Application.StartupPath;
ofile = new StreamWriter(new FileStream(startupPath+@"fx.txt",FileMode.OpenOrCreate,FileAccess.ReadWrite,FileShare.None));
ofile.WriteLine("all trace output at {0}", startupPath+@"fx.txt");

Console.WriteLine("startupPath is :{0}", startupPath);
}
public gcDemo()
{
ofile.WriteLine("gcDemo Class Constructor: {0}", ++ctor_cnt);
ofile.Flush();
}

~gcDemo()
{
try
{
ofile.WriteLine("gcDemo Class Destructor: {0}", ++dtor_cnt);
}
catch(Exception ex)
{
Console.WriteLine(ex.Message);
}
Dispose(false);

}
static public void gcObject()
{
for(int ix = 0;ix<gcDemo.Iterations;ix++)
c1 = new gcDemo();

}
}
class EntryPoint
{
public static void testM()
{
gcDemo.Iterations = 100;
gcDemo.gcObject();
}
static void Main()
{
testM();
gcDemo.c1.Dispose();
try
{
gcDemo.ofile.WriteLine("test");
}
catch(Exception ex)
{
Console.WriteLine(ex.Message);
}
System.Threading.Thread.Sleep(3000);

}
}
}