C# 如何在BeginReceive()和EndReceive()函数之后清除系统内存?
我正在做一个项目,我正在使用套接字连接到USSD服务器。该项目是一个实时24小时运行的调度程序 下面是我的C# 如何在BeginReceive()和EndReceive()函数之后清除系统内存?,c#,vb.net,sockets,C#,Vb.net,Sockets,我正在做一个项目,我正在使用套接字连接到USSD服务器。该项目是一个实时24小时运行的调度程序 下面是我的BeginReceive()和EndReceive() 公共子接收(ByVal客户端作为套接字) 将状态设置为新状态对象 state.workSocket=客户端 尝试 如果m_clientSocket.Connected,则 client.BeginReceive(state.buffer,0,StateObject.BufferSize,0,新异步回调(ReceiveCallback的地
BeginReceive()
和EndReceive()
公共子接收(ByVal客户端作为套接字)
将状态设置为新状态对象
state.workSocket=客户端
尝试
如果m_clientSocket.Connected,则
client.BeginReceive(state.buffer,0,StateObject.BufferSize,0,新异步回调(ReceiveCallback的地址),state)
其他的
连接()
如果结束
将se捕获为SocketException
logstr=se.Message
写入日志(logstr,“接收”,“接收”)
结束尝试
端接头
Public Sub-ReceiveCallback(由val-ar作为IAsyncResult)
作为StateObject的Dim状态=CType(ar.AsyncState,StateObject)
Dim客户端作为套接字=state.workSocket
Dim receiveData As String=“”
Dim sendData As String=“”
Dim字节读取为整数=client.EndReceive(ar)
如果字节读取>0,则
state.sb.Append(System.Text.Encoding.ASCII.GetString(state.buffer,0,bytesRead))
client.BeginReceive(state.buffer,0,StateObject.BufferSize,0,新异步回调(ReceiveCallback的地址),state)
receiveData=state.sb.ToString()
Me.lsBulk.Items.Insert(0,receiveData)
sendData=getReply(接收数据)
写入日志(Now.ToString&“:”&receiveData&vbCrLf,“bytesRead”,“bytesRead”)
尝试
Dim objData As[Object]=发送数据
Dim byData As Byte()=System.Text.Encoding.ASCII.GetBytes(objData.ToString())
如果m_clientSocket不是什么,那么
m_clientSocket.Send(按数据)
如果结束
写入日志(Now.ToString&“:”&sendData&vbCrLf,“sendData”,“sendData”)
将se捕获为SocketException
logstr=se.Message
写日志(logstr,“WaitForData”,“WaitForData”)
结束尝试
其他的
receiveData=state.sb.ToString()
如果接收到数据“”,则
写入日志(Now.ToString&“:”&receiveData&vbCrLf,“receiveData2”,“receiveData2”)
如果结束
如果结束
端接头
问题是这个程序占用了我太多的内存。第一次运行后需要3.5GB,然后一小时后需要4.5GB,依此类推,直到或除非我们重新启动它。这对于服务器来说是一个大麻烦,因为它在内存中分配了大量空间
我不明白在哪一点我必须清除缓冲区才能释放系统内存。缓冲区中的数据在每次写入数据库时不必保存
我想指出的是,这里的缓冲区大小每次都是10024。从我所能看出的问题是,您不断地将文本附加到
StringBuilder
实例中,并且从不释放它。您的缓冲区很好,因为它只是在重复使用已分配的内存
只需设置sb.Length=0
即可清除StringBuilder。在我看来,这是一个奇怪的API,我觉得应该有一个.Clear()
方法
当我通读您的代码时,我不确定为什么您有一个StringBuilder实例。它在其他地方做什么?
StateObject
的定义是什么?肯定会收集StringBuilder。由于OP没有提到任何实际问题,听起来OP好像不理解ManagedMemory。@我正在使用StateObject获取AsyncState的结果状态。@HansPassant您在这里提到的链接也是我的。实际上,在那里我问了BeginReceive()和EndReceive(),但我的问题仍然没有解决,所以我试图用特定的主题和问题来打开一个新的问题,以获得正确的答案。非常感谢。
Public Sub Receive(ByVal client As Socket)
Dim state As New StateObject
state.workSocket = client
Try
If m_clientSocket.Connected Then
client.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0, New AsyncCallback(AddressOf ReceiveCallback), state)
Else
Connect()
End If
Catch se As SocketException
logstr = se.Message
write_log(logstr, "Receive", "Receive")
End Try
End Sub
Public Sub ReceiveCallback(ByVal ar As IAsyncResult)
Dim state As StateObject = CType(ar.AsyncState, StateObject)
Dim client As Socket = state.workSocket
Dim receiveData As String = ""
Dim sendData As String = ""
Dim bytesRead As Integer = client.EndReceive(ar)
If bytesRead > 0 Then
state.sb.Append(System.Text.Encoding.ASCII.GetString(state.buffer, 0, bytesRead))
client.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0, New AsyncCallback(AddressOf ReceiveCallback), state)
receiveData = state.sb.ToString()
Me.lsBulk.Items.Insert(0, receiveData)
sendData = getReply(receiveData)
write_log(Now.ToString & " : " & receiveData & vbCrLf, "bytesRead", "bytesRead")
Try
Dim objData As [Object] = sendData
Dim byData As Byte() = System.Text.Encoding.ASCII.GetBytes(objData.ToString())
If m_clientSocket IsNot Nothing Then
m_clientSocket.Send(byData)
End If
write_log(Now.ToString & " : " & sendData & vbCrLf, "sendData", "sendData")
Catch se As SocketException
logstr = se.Message
write_log(logstr, "WaitForData", "waitfordata")
End Try
Else
receiveData = state.sb.ToString()
If receiveData <> "" Then
write_log(Now.ToString & " : " & receiveData & vbCrLf, "receiveData2", "receiveData2")
End If
End If
End Sub