socket异步接收,内存持续增大

sgchen 2014-06-17 05:33:47
我自己封装了一个tcpclient类,采用异步接收的方式,测试时开1000个连接发数据,发现内存一直在增大。

/// <summary>
/// 连接,一般用于客户端的创建
/// </summary>
/// <param name="ServerIP">Socket连接的IP地址</param>
/// <param name="Port">Socket连接的端口</param>
public void Connect(string ip, int port)
{
ConnectByParams(ip, port, DEFAULT_BUFFER_SIZE, DEFAULT_BUFFER_SIZE);
}
private void ConnectByParams(string ip, int port, int sendBufferSize, int receiveBufferSize)
{
_connIp = ip;
_connPort = port;
try
{
_SendBufferSize = sendBufferSize;
_ReceiveBufferSize = receiveBufferSize;
_Socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
_Socket.SendBufferSize = _SendBufferSize;
_Socket.ReceiveBufferSize = _ReceiveBufferSize;
_Socket.NoDelay = true;
_ReceiveBuffer = new byte[_Socket.ReceiveBufferSize];
_Socket.BeginConnect(ip, port, new AsyncCallback(ConnectCallBack), _Socket);
}
catch (Exception ex)
{
if (ExceptionEvent != null)
ExceptionEvent(this, new SocketEventArgs(null, "连接失败:" + ex.Message));
this.Close();
}
}
private void ConnectCallBack(IAsyncResult iar)
{
try
{
iar.AsyncWaitHandle.Close();

if (!IsConnected)
throw new Exception("");
if (SocketConnectedEvent != null)
SocketConnectedEvent(this, true);
_Socket.BeginReceive(_ReceiveBuffer, 0, _ReceiveBuffer.Length, SocketFlags.None, acRcv, _Socket);
}
catch (Exception ex)
{
if (SocketConnectedEvent != null)
SocketConnectedEvent(this, false);
if (ExceptionEvent != null)
ExceptionEvent(this, new SocketEventArgs(null, "连接失败:" + ex.Message));
this.Close();
}
}

/// <summary>
/// 接收数据
/// </summary>
private void AsynRecvCallBack(IAsyncResult iar)
{
if (_Socket == null) return; //防止其他线程关闭Socket;
try
{
int nLen = _Socket.EndReceive(iar);
iar.AsyncWaitHandle.Close();

if (nLen <= 0) //使用接收0字节作为远端Socket断开的判断
{
if (SocketDisconnectedEvent != null)
SocketDisconnectedEvent(this, null);
this.Close();
}
else
{
byte[] m_ByteDatas = new byte[nLen];
Array.Copy(_ReceiveBuffer, 0, m_ByteDatas, 0, nLen);
if (ReceivedEvent != null)
ReceivedEvent(this, new SocketEventArgs(m_ByteDatas, null));

//继续接收
_Socket.BeginReceive(_ReceiveBuffer, 0, _ReceiveBuffer.Length, SocketFlags.None, acRcv, null);
}
}
catch (SocketException ex)
{
if (ExceptionEvent != null)
ExceptionEvent(this, new SocketEventArgs(null, "Type:" + ex.GetType().Name + ";ErrorCode:" + ex.ErrorCode.ToString() + ";Msg:" + ex.Message +
"\r\n" + ex.StackTrace));

if (ex.ErrorCode != 10035)
{
if (SocketDisconnectedEvent != null)
SocketDisconnectedEvent(this, null);
this.Close();
}
}
catch (Exception ex)
{
if (ExceptionEvent != null)
ExceptionEvent(this, new SocketEventArgs(null, ex.GetType().Name + ":" + ex.Message + "\r\n" + ex.StackTrace));
}
}

查了很多地方都没发现哪里提到过异步接收会有这个问题,尝试增加iar.AsyncWaitHandle.Close();也无效;

byte[] m_ByteDatas = new byte[nLen];
Array.Copy(_ReceiveBuffer, 0, m_ByteDatas, 0, nLen);
if (ReceivedEvent != null)
ReceivedEvent(this, new SocketEventArgs(m_ByteDatas, null));
这一段注释掉也不行。

奇了怪了,哪位大侠碰到过类似的问题,求解....
...全文
1320 18 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
18 条回复
切换为时间正序
请发表友善的回复…
发表回复
iamlilinfeng 2016-10-21
  • 打赏
  • 举报
回复
这个问题我也遇到了。上面说的方法都不是根本问题,代码看都来都对,但就是内存在增大。我们是要找出哪些对象被挂起即:GC回收不了。 解决方案:使用:.NET Memory Profiler 4.0工具查看大对象的调用堆栈。找出根本原因并解决。
大强快跑 2015-03-01
  • 打赏
  • 举报
回复
我也碰到这样的问题,感觉是网络带宽不够造成的,还没有找到解决的办法。
dengshushu68 2014-07-09
  • 打赏
  • 举报
回复
楼主,你的问题解决了吗? 我的公司,家里电脑都这样哦。。 这里有篇文章说这样可以解决,但是我拿下来,用他原带代码及修改后的测试都还是会持续增加。 http://blog.csdn.net/ani/article/details/7182035
bdmh 2014-06-18
  • 打赏
  • 举报
回复
new了大量的缓存,又得不到及时的释放
sgchen 2014-06-18
  • 打赏
  • 举报
回复
最奇怪是就是我的公司电脑是这样,试了其他人的同样的系统也不会出现内存一直增长的问题
sgchen 2014-06-18
  • 打赏
  • 举报
回复
引用 13 楼 ZIP_xG 的回复:
[quote=引用 12 楼 sgchen2000 的回复:] [quote=引用 11 楼 ZIP_xG 的回复:] 主动调用垃圾释放看看 如果调用后大幅下降就不用管了,.Net会自动处理的
试过家GC.Collect(),不管用[/quote] 你copy出去的byte[]拿来干什么了? 主要原因是你引发事件的byte[]没有释放造成的[/quote] 前面说过了,即使注释掉 byte[] m_ByteDatas = new byte[nLen]; Array.Copy(_ReceiveBuffer, 0, m_ByteDatas, 0, nLen); if (ReceivedEvent != null) ReceivedEvent(this, new SocketEventArgs(m_ByteDatas, null)); 也是一样
Kation 2014-06-18
  • 打赏
  • 举报
回复
引用 12 楼 sgchen2000 的回复:
[quote=引用 11 楼 ZIP_xG 的回复:] 主动调用垃圾释放看看 如果调用后大幅下降就不用管了,.Net会自动处理的
试过家GC.Collect(),不管用[/quote] 你copy出去的byte[]拿来干什么了? 主要原因是你引发事件的byte[]没有释放造成的
sgchen 2014-06-18
  • 打赏
  • 举报
回复
引用 11 楼 ZIP_xG 的回复:
主动调用垃圾释放看看 如果调用后大幅下降就不用管了,.Net会自动处理的
试过家GC.Collect(),不管用
Kation 2014-06-18
  • 打赏
  • 举报
回复
主动调用垃圾释放看看 如果调用后大幅下降就不用管了,.Net会自动处理的
sgchen 2014-06-18
  • 打赏
  • 举报
回复
引用 8 楼 tcmakebest 的回复:
1000个能测出什么问题,请用10万个来测,再看使用的内存数量,如果是线性上涨那才是有问题.
1000个已经发现问题了,因为是持续接收数据,所以很明显看见每次不断增大,以1000条/秒的频率发数据,半小时左右程序的内存就达到500M了。
嘿呀土豆 2014-06-18
  • 打赏
  • 举报
回复
不能光接收用完要释放的嘛!!
tcmakebest 2014-06-18
  • 打赏
  • 举报
回复
1000个能测出什么问题,请用10万个来测,再看使用的内存数量,如果是线性上涨那才是有问题.
sgchen 2014-06-18
  • 打赏
  • 举报
回复
引用 6 楼 SwingingMace 的回复:
[quote=引用 4 楼 sgchen2000 的回复:] [quote=引用 2 楼 SwingingMace 的回复:] 1、测试不发不收,只连接。 2、测试只发不收。 3、测试只收不发。 这样可以判断是收发的问题,还是收与发哪一个出了问题。
确实这样试了,是收数据造成的。[/quote] 每收一次就清空一次buff了吗?[/quote] 我是这样写的: _Socket.BeginReceive(_ReceiveBuffer, 0, _ReceiveBuffer.Length, SocketFlags.None, acRcv, null); _ReceiveBuffer是局部变量,每次都是用这个,还有必要清空吗?
SwingingMace 2014-06-18
  • 打赏
  • 举报
回复
引用 4 楼 sgchen2000 的回复:
[quote=引用 2 楼 SwingingMace 的回复:] 1、测试不发不收,只连接。 2、测试只发不收。 3、测试只收不发。 这样可以判断是收发的问题,还是收与发哪一个出了问题。
确实这样试了,是收数据造成的。[/quote] 每收一次就清空一次buff了吗?
sgchen 2014-06-18
  • 打赏
  • 举报
回复
很奇怪的是,我在公司的机子上试是这种状况,拿回家试又没有问题。 家里装的是windows7 sp1 64位,公司是windows7 sp1 32位。 我有在windows2008下测试也没有问题。 我在公司的机子上尝试用.net framework 4.5,也是同样的结果。 真不明白系统哪个地方会导致这种现象。
sgchen 2014-06-18
  • 打赏
  • 举报
回复
引用 2 楼 SwingingMace 的回复:
1、测试不发不收,只连接。 2、测试只发不收。 3、测试只收不发。 这样可以判断是收发的问题,还是收与发哪一个出了问题。
确实这样试了,是收数据造成的。
SwingingMace 2014-06-18
  • 打赏
  • 举报
回复
1、测试不发不收,只连接。 2、测试只发不收。 3、测试只收不发。 这样可以判断是收发的问题,还是收与发哪一个出了问题。
wangnaisheng 2014-06-17
  • 打赏
  • 举报
回复
.dispose() 释放资源试试

111,093

社区成员

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

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

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