gpt4 book ai didi

c# - 服务器/客户端。客户端使用大量内存

转载 作者:太空宇宙 更新时间:2023-11-03 14:10:22 24 4
gpt4 key购买 nike

这是我的第一个问题,希望您能帮助我。

我有 2 个程序,一个服务器和一个客户端,我的问题出在客户端。

运行 2 或 3 天后,它使用了超过 300MB 的 RAM(我可以通过查看 TaskManager 来判断)并且从未释放它!另外,我不得不说这个客户端每秒从 GPS 设备接收数据。我用 ANTS Memory Profiler 分析了我的客户端,我注意到我多次创建了一个对象,但它们从未被销毁。

这是我的代码:

private static TcpClient _client;
private readonly ManualResetEvent _receiveDone = new ManualResetEvent(false);

public void Receive()
{
if (_client.Connected)
{
_receiveDone.Reset();
ObjectState state = new ObjectState();
state.WorkSocket = _client.Client;
state.Data = new byte[_client.ReceiveBufferSize];
_client.Client.BeginReceive(state.Data, 0, Convert.ToInt32(_client.ReceiveBufferSize), 0, ReceiveCallback, state);

if (!_receiveDone.WaitOne(20000))
{
//after 20 seconds WITHOUT RECEIVING DATA, do some code to test if the connection is alive
}
}
}

void ReceiveCallback(IAsyncResult ar)
{
ObjectState state = (ObjectState)ar.AsyncState;
Socket client = state.WorkSocket;
if (client.Connected)
{
int bytesRead = client.EndReceive(ar);
if (bytesRead > 0)
{
string response = Encoding.ASCII.GetString(state.Data, 0, bytesRead);
doProcess(response);
client.BeginReceive(state.Data, 0, Convert.ToInt32(_client.ReceiveBufferSize), 0, ReceiveCallback, state);
_receiveDone.Set();
}
else
{
//Disconnection
}
}
}

public class ObjectState
{
public Socket WorkSocket;
public byte[] Data;
}

ANTS Memory Profiler 告诉我我有数千个 byte[] 的事件实例。 (因为我总是创建 ObjectState 的新实例)

我想做的第一件事:处置我在调用 BeginReceive 后创建的所有 ObjectState,但我只收到第一条消息。

然后我想停止使用 ObjectState... 怎么办?这是我修改后的代码:

private _data byte[];

public void Receive()
{
if (_client.Connected)
{
_receiveDone.Reset();
_data = new byte[_client.ReceiveBufferSize];
_client.Client.BeginReceive(_data, 0, Convert.ToInt32(_client.ReceiveBufferSize), 0, ReceiveCallback, null);

if (!_receiveDone.WaitOne(20000))
{
//after 20 seconds of inactivity do some code to test if the connectio is alive
}
}
}

void ReceiveCallback(IAsyncResult ar)
{
Socket client = _cliente.Client;
if (client.Connected)
{
int bytesRead = client.EndReceive(ar);
if (bytesRead > 0)
{
string response = Encoding.ASCII.GetString(_data, 0, bytesRead);
doProcess(response);
client.BeginReceive(_data, 0, Convert.ToInt32(_client.ReceiveBufferSize), 0, ReceiveCallback, null);
_receiveDone.Set();
}
else
{
//Disconnection
}
}
}

这是怎么回事?我只收到第一条消息,所以这不好。然后,如果我删除 _receiveDone.Set 它会收到所有消息,但是 _receiveDone.WaitOne(2000) 总是每 20 秒执行一次,无论我是否真的收到数据,这也不好。

所以我的问题是,我可以做些什么来减少这么多 RAM 的使用?我希望这能很好地解释我的问题。

编辑:我上传了这些图片,希望它们也能有所帮助。 Summary Instant Retention Graph

最佳答案

if (client.Connected)
{
int bytesRead = client.EndReceive(ar);
// etc..

调用 EndReceive 不是可选的,您必须调用它,否则会泄漏资源。使用 try/catch 捕获 ObjectDisposedException。

关于c# - 服务器/客户端。客户端使用大量内存,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8039340/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com