现在有一个用C#写的windows service,每一分钟执行一次,其中有一个写log日志的方法:
String path;
FileStream log;
StreamWriter writer; public void writeLog(LogLevel outLevel, String[] data)
{
lock (lockobj)
{ if (level <= (int)outLevel)
{
try
{
String rotatePath;
if (path.Contains("_D_A_T_E_"))
{
rotatePath = path.Replace("_D_A_T_E_", "_" + DateTime.Now.ToString("yyyyMMdd"));
}
else if (path.Contains("_M_O_N_T_H_"))
{
rotatePath = path.Replace("_M_O_N_T_H_", "_" + DateTime.Now.ToString("yyyyMM"));
}
else
{
rotatePath = path;
}
log = new FileStream(rotatePath, FileMode.Append, FileAccess.Write, FileShare.Read);
writer = new StreamWriter(log); writer.Write(
"[" + System.DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss") + "] " +
"[" + outLevel + "] "); writer.Write("["); StringBuilder sb = new StringBuilder();
foreach (String str in data)
{
sb.Append(str + ",");
}
writer.Write(sb.ToString().TrimEnd(','));
writer.Write("]\n");
writer.Flush();
writer.Close();
writer.Dispose();
}
catch
{
}
}
}
} 现在的问题是:writer = new StreamWriter(log);
writer 对象生成后,资源释放不了,用perfmon监视查看,内存消耗差不多每一分钟都有增长。
其他所有的都注释掉了,单单运行log输出这一块。
GC.SuppressFinalize(this);
using(writer = new StreamWriter(log)){ }
都试过,还是不行
想问一下如何能彻底释放掉write的资源,谢谢
String path;
FileStream log;
StreamWriter writer; public void writeLog(LogLevel outLevel, String[] data)
{
lock (lockobj)
{ if (level <= (int)outLevel)
{
try
{
String rotatePath;
if (path.Contains("_D_A_T_E_"))
{
rotatePath = path.Replace("_D_A_T_E_", "_" + DateTime.Now.ToString("yyyyMMdd"));
}
else if (path.Contains("_M_O_N_T_H_"))
{
rotatePath = path.Replace("_M_O_N_T_H_", "_" + DateTime.Now.ToString("yyyyMM"));
}
else
{
rotatePath = path;
}
log = new FileStream(rotatePath, FileMode.Append, FileAccess.Write, FileShare.Read);
writer = new StreamWriter(log); writer.Write(
"[" + System.DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss") + "] " +
"[" + outLevel + "] "); writer.Write("["); StringBuilder sb = new StringBuilder();
foreach (String str in data)
{
sb.Append(str + ",");
}
writer.Write(sb.ToString().TrimEnd(','));
writer.Write("]\n");
writer.Flush();
writer.Close();
writer.Dispose();
}
catch
{
}
}
}
} 现在的问题是:writer = new StreamWriter(log);
writer 对象生成后,资源释放不了,用perfmon监视查看,内存消耗差不多每一分钟都有增长。
其他所有的都注释掉了,单单运行log输出这一块。
GC.SuppressFinalize(this);
using(writer = new StreamWriter(log)){ }
都试过,还是不行
想问一下如何能彻底释放掉write的资源,谢谢
writer = new StreamWriter(log);
改为
using(log = new FileStream(rotatePath, FileMode.Append, FileAccess.Write, FileShare.Read);)
{
...
log.close();
}
String path;
FileStream log;
StreamWriter writer;
宣告到方法裹头
应该是会释放掉的~
不只log没释放的原因,曾经这样写过:
using (log = new FileStream(rotatePath, FileMode.Append, FileAccess.Write, FileShare.Read))
{
using (writer = new StreamWriter(log))
{
writer.Write(
"[" + System.DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss") + "] " +
"[" + outLevel + "] "); writer.Write("["); StringBuilder sb = new StringBuilder();
foreach (String str in data)
{
sb.Append(str + ",");
}
writer.Write(sb.ToString().TrimEnd(','));
writer.Write("]\n");
writer.Flush();
writer.Close();
writer.Dispose();
log.Flush();
log.Close();
log.Dispose();
}
}
还是没用的。
把有关write的内容注释掉,只留有log部分,内存变量不变。
所以感觉和log部分无关。
把你中间的代码改了下 try
{
using (FileStream log = new FileStream(rotatePath, FileMode.Append, FileAccess.Write, FileShare.Read))
{
using (StreamWriter writer = new StreamWriter(log))
{
writer.Write(
"[" + System.DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss") + "] " +
"[" + outLevel + "] "); writer.Write("["); StringBuilder sb = new StringBuilder();
foreach (String str in data)
{
sb.Append(str + ",");
}
writer.Write(sb.ToString().TrimEnd(','));
writer.Write("]\n");
writer.Flush();
writer.Close();
writer.Dispose();
}
log.Close();
log.Dispose();
}
}
catch(Exception ex)
{
Console.WriteLine(ex.Message);
}
StreamWriter writer;
写到函数头试试看还有
writer.Close();
writer.Dispose();写到finally里面比较好
if (writer != null) {
writer.Close();
writer.Dispose();
}我个人觉得这些法没有问题
lock (lockobj),但是前提是lockobj是个静态变量,或者该log操作类只有唯一一个实例
log.close();
log = null;
writer .close();
writer = null;
这个样子呢
{
FileStream log;
StreamWriter writer; lock (lockobj)
{ if (level <= (int)outLevel)
{
try
{
String rotatePath;
if (path.Contains("_D_A_T_E_"))
{
rotatePath = path.Replace("_D_A_T_E_", "_" + DateTime.Now.ToString("yyyyMMdd"));
}
else if (path.Contains("_M_O_N_T_H_"))
{
rotatePath = path.Replace("_M_O_N_T_H_", "_" + DateTime.Now.ToString("yyyyMM"));
}
else
{
rotatePath = path;
}
log = new FileStream(rotatePath, FileMode.Append, FileAccess.Write, FileShare.Read);
//writer = new StreamWriter(log); //writer.Write(
// "[" + System.DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss") + "] " +
// "[" + outLevel + "] "); //writer.Write("["); //StringBuilder sb = new StringBuilder();
//foreach (String str in data)
//{
// sb.Append(str + ",");
//}
//writer.Write(sb.ToString().TrimEnd(','));
//writer.Write("]\n");
//writer.Flush();
//writer.Close(); }
catch
{
}
}
}
}
如果把write的部分注释掉,运行的话,内存是不增加的
log = new FileStream(rotatePath, FileMode.Append, FileAccess.Write, FileShare.Read);
writer = new StreamWriter(log);放到类的构造函数!
{
}
试了,不是正解,放到构造函数后,只第一次能出力log,后面的就都不能出力了
不是,我也曾认为是这个原因,加了 log.Flush();
log.Close();
log.Dispose();
但没有效果,不是这个原因
那就不知道什么原因了,这种情况没遇到过。
把写日志的方法写成一个类
然后
String path;
FileStream log;
StreamWriter writer;
没必要是全局的。
如果在不行(就log4net),实在不想用就请高手请教,我也学习下。