C#Windows服务的内存一直在疯涨!!!

mywisest 2008-10-21 05:17:18
用C#开发了一个基于Remoting的分布式应用,服务器端作为Service运行,在服务器端存在一个比较大的Int[]变量。现在的问题是:
系统运行时内存会一直疯涨,没一会就到1G了,然后就是系统崩掉。

关于垃圾回收,我已经:
1.实现了IDispose,并且在使用相关对象后及时的Dispose掉了;
2.在继承MarshalByRefObject的类中添加了一个线程进行不断的回收垃圾;

通过WinDbg分析Dump文件后,发现ServiceBase会将WaitForPendingFinalizers阻塞在那里。

不知有没有人能够解决这个问题?
...全文
390 17 打赏 收藏 转发到动态 举报
写回复
用AI写文章
17 条回复
切换为时间正序
请发表友善的回复…
发表回复
seven2 2009-03-08
  • 打赏
  • 举报
回复
类似遇过,在sever config 配置了内存回收的时间,时间设置较小,强制回收
<system.runtime.remoting>
<application name="RemoteServer">
<!--这里配置内存回收-->
<lifetime leaseTime="10M" sponsorshipTimeOut="600S" renewOnCallTime="200S" leaseManagerPollTime="100S"></lifetime>
CruelYoung123 2008-11-16
  • 打赏
  • 举报
回复
不懂楼主说的生存时间。。。。
风骑士之怒 2008-11-16
  • 打赏
  • 举报
回复
生产时间? 学习...
mywisest 2008-11-16
  • 打赏
  • 举报
回复
问题已经自己解决,原因是需要实现生存时间.哈哈!
wartim 2008-10-23
  • 打赏
  • 举报
回复

#region Dispose
/// <summary>
/// 销毁。
/// </summary>
void IDisposable.Dispose()
{
_heights = null;
_index0 = null;
_index1 = null;
GC.SuppressFinalize(this);
}
#endregion
mywisest 2008-10-23
  • 打赏
  • 举报
回复
看分析应该都MTA的程序。
我也没调用过这个函数,如果有肯定是ServiceBase调的吧。
我很懒 2008-10-22
  • 打赏
  • 举报
回复
是不是手动调用了GC.WaitForPendingFinalizers?
STA的程序是不能调用这个方法的
赞同
up
abcyzq 2008-10-22
  • 打赏
  • 举报
回复
先占位,在学习。
mywisest 2008-10-22
  • 打赏
  • 举报
回复
我用windgb对该进程的dump文件进行了分析,发现确实是如此。
在Service中不调用终结器的,导致对象的内容越来越多!!!
dump的结果如下:
http://60.12.13.148/files/dump.txt
mywisest 2008-10-21
  • 打赏
  • 举报
回复
/// <summary>
/// 保存当前实例至文件,同时保存至数据库。
/// </summary>
public static void Save(SceneDataEntity entity)
{
try
{
entity.IsChanged = false;
//保存至文件
byte[] _buffer = null;
try
{
string _saveToFile = FileUtil.GetAppConfig("SceneDataSaveToFile").ToLower().Trim();
bool NeedSaveToFile = (_saveToFile == "true" || _saveToFile == "yes" || _saveToFile == "1");
if (NeedSaveToFile)
{
_buffer = BaseHelper.Serialize(entity);
_buffer = CompressUtil.Compress(_buffer);
FileUtil.WriteAllBytes(entity.FileName, _buffer);
}
}
catch (Exception ex)
{
TraceUtility.Trace("SceneDataEntity-SaveFile", string.Format("Save scene data entity is fail. Scene no is {0}, error message is {1}", entity.No, ex.Message));
}
TraceUtility.Assert(entity != null, "SaveSceneEntity", String.Format("Need save entity is null."));
if (entity.Size > 0)
{
//保存至数据库
int length = entity.Heights.Length * 4;
_buffer = new byte[length];
IntPtr _ptr = IntPtr.Zero;
//Heights
try
{
_ptr = Marshal.AllocHGlobal(length);
Marshal.Copy(entity.Heights, 0, _ptr, entity.Heights.Length);
Marshal.Copy(_ptr, _buffer, 0, length);
SaveData(SceneDataStyle.Scene, entity.No, entity.Size, _buffer);
}
catch (Exception ex)
{
TraceUtility.Trace("SceneEntity-SaveDB-Heights", string.Format("Save scene data entity is fail. Scene no is {0}, error message is {1}", entity.No, ex.Message));
}
finally
{
Marshal.FreeHGlobal(_ptr);
}
//Index0
try
{
length = entity.Index0.Length * 4;
_buffer = new byte[length];
_ptr = Marshal.AllocHGlobal(length);
Marshal.Copy(entity.Index0, 0, _ptr, entity.Index0.Length);
Marshal.Copy(_ptr, _buffer, 0, length);
SaveData(SceneDataStyle.Index0, entity.No, entity.Size - 1, _buffer);
}
catch (Exception ex)
{
TraceUtility.Trace("SceneEntity-SaveDB-Index0", string.Format("Save scene data entity is fail. Scene no is {0}, error message is {1}", entity.No, ex.Message));
}
finally
{
Marshal.FreeHGlobal(_ptr);
}
//Index1
try
{
length = entity.Index1.Length * 4;
_buffer = new byte[length];
_ptr = Marshal.AllocHGlobal(length);
Marshal.Copy(entity.Index1, 0, _ptr, entity.Index1.Length);
Marshal.Copy(_ptr, _buffer, 0, length);
SaveData(SceneDataStyle.Index1, entity.No, entity.Size - 1, _buffer);
}
catch (Exception ex)
{
TraceUtility.Trace("SceneEntity-SaveDB-Index1", string.Format("Save scene data entity is fail. Scene no is {0}, error message is {1}", entity.No, ex.Message));
}
finally
{
Marshal.FreeHGlobal(_ptr);
}
}
}
catch (Exception e)
{
TraceUtility.Trace("SceneDataEntity-SaveDB", string.Format("Save scene data entity is fail. Scene no is {0}, error message is {1}", entity.No, e.Message));
}
}
mywisest 2008-10-21
  • 打赏
  • 举报
回复
#region 静态方法
public static SceneDataEntity Initialize(string no, int size)
{
SceneDataEntity _entity = new SceneDataEntity(no);
try
{
if (FileUtil.Exists(_entity.FileName))
{
byte[] _buffer = FileUtil.ReadAllBytes(_entity.FileName);
_buffer = CompressUtil.Decompress(_buffer);
_entity = BaseHelper.Deserialize(_buffer) as SceneDataEntity;
}
else
{
//从数据库获取
if (size > 0) //如图有地形
{
_entity.Size = size;
_entity.Heights = new float[size * size];
int indexSize = size - 1;
_entity.Index0 = new int[indexSize * indexSize];
_entity.Index1 = new int[indexSize * indexSize];
//
byte[] _retBytes0 = null;
IntPtr _ptr = IntPtr.Zero;
//Index0
try
{
_retBytes0 = DBHelper.ReadBinaryData(SceneDataStyle.Index0, no, string.Format("{0} - {1}", 0, indexSize), 0, indexSize);
if (_retBytes0 != null && _retBytes0.Length > 0)
{
_ptr = Marshal.AllocHGlobal(_retBytes0.Length);
Marshal.Copy(_retBytes0, 0, _ptr, _retBytes0.Length);
Marshal.Copy(_ptr, _entity.Index0, 0, indexSize * indexSize);
}
}
catch (Exception ex)
{
TraceUtility.Trace("SceneEntity-Initialize-Index0", string.Format("SceneNo:{0} Size:{1} Error:{2}", no, size, ex.Message));
}
finally
{
Marshal.FreeHGlobal(_ptr);
_retBytes0 = null;
}

//Index1
try
{
_retBytes0 = DBHelper.ReadBinaryData(SceneDataStyle.Index1, no, string.Format("{0} - {1}", 0, indexSize), 0, indexSize);
if (_retBytes0 != null && _retBytes0.Length > 0)
{
_ptr = Marshal.AllocHGlobal(_retBytes0.Length);
Marshal.Copy(_retBytes0, 0, _ptr, _retBytes0.Length);
Marshal.Copy(_ptr, _entity.Index1, 0, indexSize * indexSize);
}
}
catch (Exception ex)
{
TraceUtility.Trace("SceneEntity-Initialize-Index1", string.Format("SceneNo:{0} Size:{1} Error:{2}", no, size, ex.Message));
}
finally
{
Marshal.FreeHGlobal(_ptr);
_retBytes0 = null;
}
//Height
try
{
_retBytes0 = DBHelper.ReadBinaryData(SceneDataStyle.Scene, no, string.Format("{0} - {1}", 0, size), 0, size);
if (_retBytes0 != null && _retBytes0.Length > 0)
{
_ptr = Marshal.AllocHGlobal(_retBytes0.Length);
Marshal.Copy(_retBytes0, 0, _ptr, _retBytes0.Length);
Marshal.Copy(_ptr, _entity.Heights, 0, _entity.Heights.Length);
}
}
catch (Exception ex)
{
TraceUtility.Trace("SceneEntity-Initialize-Height", string.Format("SceneNo:{0} Size:{1} Error:{2}", no, size, ex.Message));
}
finally
{
Marshal.FreeHGlobal(_ptr);
_retBytes0 = null;
}
}
//在本地保存一份附件
try
{
FileUtil.WriteAllBytes(_entity.FileName, CompressUtil.Compress(BaseHelper.Serialize(_entity)));
}
catch (Exception e)
{
TraceUtility.Trace("Initialize-WriteAllBytes", string.Format("保存本地附件时出错:{0}", e.Message));
}
}
}
catch (System.Exception e)
{
TraceUtility.Trace("SceneDataEntity-Initialize", string.Format("Initialize scene data entity is fail. Scene no is {0}, error message is {1}", no, e.Message));
}
return _entity;
}

mywisest 2008-10-21
  • 打赏
  • 举报
回复
实体类:
[Serializable]
public class SceneDataEntity : IDisposable, ICloneable
{
#region 构造&释构
/// <summary>构造本实体时必须传入场景编号</summary>
public SceneDataEntity(string no)
{
_no = no;
}
~SceneDataEntity()
{
Dispose(false);
}
#endregion
#region 属性
private string _no;
/// <summary>场景编号。</summary>
public string No { get { return _no; } }
/// <summary>场景大小。</summary>
private int _size;
public int Size { get { return _size; } set { _size = value; } }
/// <summary>场景的高度数据,长度为Size * Size。</summary>
private float[] _heights;
public float[] Heights { get { return _heights; } set { _heights = value; } }
/// <summary>场景混合纹理的第一部分数据。</summary>
private int[] _index0;
public int[] Index0 { get { return _index0; } set { _index0 = value; } }
/// <summary>场景混合纹理的第二部分数据。</summary>
private int[] _index1;
public int[] Index1 { get { return _index1; } set { _index1 = value; } }
/// <summary>数据是否被更新。</summary>
private bool _isChanged;
public bool IsChanged { get { return _isChanged; } set { _isChanged = value; } }

private bool isDisposed;
#endregion


private static void SaveData(SceneDataStyle style, string sceneNo, int size, byte[] buffer)
{
List<byte[]> _rowData = new List<byte[]>(size);
int _startIndex = 0;
int _len = size * 4;
byte[] _buffer = new byte[_len];
do
{
Array.Copy(buffer, _startIndex, _buffer, 0, _len);
_rowData.Add(_buffer);
_startIndex += _len;
_buffer = new byte[_len];
} while (_startIndex < buffer.Length);

DBHelper.SaveBinaryData(style, sceneNo, 0, 0, _rowData);
}
#endregion

#region Dispose
/// <summary>
/// 销毁。
/// </summary>
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}

protected virtual void Dispose(bool disposing)
{
if (!isDisposed)
{
if (disposing)
{
}
_heights = null;
_index0 = null;
_index1 = null;
}
isDisposed = true;
}
#endregion

#region ICloneable
public object Clone()
{
SceneDataEntity _entity = new SceneDataEntity(this.No);
_entity.Heights = this.Heights;
_entity.Index0 = this.Index0;
_entity.Index1 = this.Index1;
_entity.Size = this.Size;

return _entity;
}
#endregion
}
shalen520 2008-10-21
  • 打赏
  • 举报
回复
是不是手动调用了GC.WaitForPendingFinalizers?
STA的程序是不能调用这个方法的

感觉你的第二步做法有问题
mywisest 2008-10-21
  • 打赏
  • 举报
回复
我在继承MarshalByRefObject的类有个定时保存的函数:

Queue<SceneDataEntity> _saveEntities = new Queue<SceneDataEntity>();
/// <summary>保存当前所有的数据集合。 </summary>
public void Save()
{
//1.取出所有已经改过的集合
//2.保存数据
//3.更改集合中的项;
_saveEntities = new Queue<SceneDataEntity>();
lock (_syncRoot)
{
//获取已经发生变动的场景
foreach (SceneDataEntity _entity in AllSceneData.Values)
if (_entity.IsChanged)
_saveEntities.Enqueue((SceneDataEntity)_entity.Clone());
//更改IsChanged值
foreach (SceneDataEntity entity in _saveEntities)
AllSceneData[entity.No] = entity;
}
//保存数据
while (_saveEntities.Count > 0)
{
SceneDataEntity _saveEntity = _saveEntities.Dequeue();
SceneDataEntity.Save(_saveEntity);
_saveEntity.Dispose();
_saveEntity = null;
}
_saveEntities = null;
TraceUtility.Trace("SaveToDb", string.Format("Use Memory : {0} bytes.", GC.GetTotalMemory(false)));
GC.Collect();
TraceUtility.Trace("SaveToDb", string.Format("Use Memory(After Collect) : {0} bytes.", GC.GetTotalMemory(false)));
}
mywisest 2008-10-21
  • 打赏
  • 举报
回复
你要什么代码?是Service还是MarshalByRefObject的?
zhengxy22 2008-10-21
  • 打赏
  • 举报
回复
查下试试
lovehongyun 2008-10-21
  • 打赏
  • 举报
回复
得查一下你的具体代码.找出原因.

光说是不行的.-_-!

110,536

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧