我正在从Windows 8中的流套接字中递归地读取数据。它工作得很好,但存在内存泄漏。也就是说,每次读取后,内存大小都会增加。有人能告诉我这是怎么回事吗?这是我的实现
public async Task ReadSocket(StreamSocket Socket)
{
try
{
uint intBytesRead;
var dataReader = new DataReader(Socket.InputStream);
dataReader.InputStreamOptions = InputStreamOptions.Partial;
intBytesRead = await dataReader.LoadAsync(4);
if (intBytesRead == 0)
{
OnDisconnect(Socket);
return;
}
while (intBytesRead < 4)
{
uint read = await dataReader.LoadAsync((uint)4 - intBytesRead);
if (read == 0)
{
OnDisconnect(Socket);
return;
}
intBytesRead += read;
}
byte[] data = new byte[4];
dataReader.ReadBytes(data);
int lenHTN = BitConverter.ToInt32(data, 0);
int length = CommonUtil.ConvertNToH(lenHTN);
if (length < 1)
{
OnDisconnect(Socket);
return;
}
data = new byte[length];
uint dataBytesRead = await dataReader.LoadAsync((uint)length);
if (dataBytesRead == 0)
{
OnDisconnect(Socket);
return;
}
while (dataBytesRead < length)
{
uint read = await dataReader.LoadAsync((uint)length - dataBytesRead);
if (read == 0)
{
OnDisconnect(Socket);
return;
}
dataBytesRead += read;
}
dataReader.ReadBytes(data);
Debug.WriteLine("Check Memory Status");
}
catch (Exception ex)
{
Debug.WriteLine(ex.ToString());
if (SocketError.GetStatus(ex.HResult) == SocketErrorStatus.ConnectionResetByPeer)
{
OnDisconnect(Socket);
return;
}
}
await ReadSocket(Socket);}
这是输出
Check Memory Status目前:25限值:314
检查内存状态当前:25 Memory限制:314 Memory
检查内存状态当前:25 Memory限制:314 Memory
检查内存状态当前:25 Memory限制:314 Memory
检查内存状态当前:26 Memory限制:314 Memory
检查内存状态当前:26 Memory限制:314 Memory
检查内存状态当前:27 Memory限制:314 Memory
检查内存状态当前:27 Memory限制:314 Memory
检查内存状态当前:27 Memory限制:314 Memory
。。。
检查内存状态当前:72 Memory限制:314 Memory
检查内存状态当前:72 Memory限制:314 Memory
。。由于OutOfmemory,它一直持续到应用程序崩溃。
发布于 2013-09-10 16:41:44
导致内存泄漏的原因是递归。谈到内存,async方法的行为几乎与普通同步方法相同,只是它们的局部变量存储在堆中。
因此,在您的代码中,data的内存、方法中的其他变量以及以前迭代中返回的一些附加信息(比如方法返回的Task )从未被释放,这导致了您的泄漏。
如果您在递归data = null;之前添加了await,这可能会显著改善情况,但不会修复泄漏。
为此,您需要将代码从递归更改为普通循环。类似于:
bool finished = false;
while (!finished)
{
finished = await ReadSingleSocket(socket);
}其中,ReadSingleSocket()是一个包含来自ReadSocket()的大部分代码的方法,但递归await除外。当读取应该停止时,它将返回true,否则将返回false。
https://stackoverflow.com/questions/18720984
复制相似问题