C# TCP 连接在接收反序列化时使用了太多内存 类
C# TCP Connection Uses too Much Memory when Receiving Deserialized Classes
我正在尝试制作一个 C# 客户端/服务器程序,它可以通过序列化、反序列化和发送来在两个程序(在同一台计算机或不同计算机上)之间发送 类 TCP 但我不知道为什么程序使用了太多内存。执行几秒钟后,程序(客户端和服务器)都达到 100MB,并且使用的内存继续增加。我尝试同时使用 TCP 连接和命名管道,但问题仍然存在。所以我认为这是序列化和反序列化中的一个问题(也许),但我不知道。你有什么想法吗?
Class用于序列化和反序列化:
class ObjectSerializer {
public ObjectSerializer() { }
public MemoryStream Serialize(Object obj, Type[] types) {
MemoryStream memoryStream = new MemoryStream();
XmlSerializer xmlSerializer = new XmlSerializer(typeof(Object), types);
xmlSerializer.Serialize(memoryStream, obj);
return memoryStream;
}
public Object Deserialize(MemoryStream memoryStream, Type[] types) {
XmlSerializer xmlSerializer = new XmlSerializer(typeof(Object), types);
return (Object)xmlSerializer.Deserialize(memoryStream);
}
}
Class 包含用于发送和接收消息的方法以及 类:
class TCPMethods {
private NetworkStream networkStream;
private Type[] types;
//Constructor receiving a socket
public TCPMethods(Socket socket, Type[] types) {
this.networkStream = new NetworkStream(socket);
this.types = types;
}
//Constructor receiving a stream
public TCPMethods(NetworkStream networkStream, Type[] types) {
this.networkStream = networkStream;
this.types = types;
}
/*
*
* FUNCTIONS THAT SEND AND RECEIVE DATA THROUGH THE NETWORKSTREAM
*
*/
public void SendMessage(String message) {
//I serialize the message and send it
byte[] serializedMessage = Encoding.UTF8.GetBytes(message);
networkStream.Write(serializedMessage, 0, serializedMessage.Length);
}
public void SendObject(Object obj) {
ObjectSerializer convertObject = new ObjectSerializer();
//I call the class function to serialize the object and send it
byte[] serializedObject = convertObject.Serialize(obj, types).ToArray();
//Calculate and send the length of the byte array byte[] objectLenght = BitConverter.GetBytes(serializedObject.Length);
networkStream.Write(objectLenght, 0, objectLenght.Length);
networkStream.Write(serializedObject, 0, serializedObject.Length);
}
public String ReceiveMessage() {
//String in which the complete message will be inserted
String completeMessage = String.Empty;
//Byte array in which I save the message I am going to read from the stream
byte[] messageBuffer = new byte[512];
do {
//I read and save the bytes of the message from the stream
networkStream.Read(messageBuffer, 0, messageBuffer.Length);
//I convert to string and concatenate the message part
completeMessage += Encoding.UTF8.GetString(messageBuffer);
//I clear the byte buffer
messageBuffer = new byte[512];
//I repeat until I finish reading the message
} while (networkStream.DataAvailable);
return completeMessage;
}
public Object ReceiveObject() {
ObjectSerializer convertObject = new ObjectSerializer();
//I declare and read the variable which contains the length of the object
byte[] objectLenght = new byte[sizeof(int)];
networkStream.Read(objectLenght, 0, objectLenght.Length);
//Array in which the object will be saved
byte[] objectBuffer = new byte[BitConverter.ToInt32(objectLenght, 0)];
//I read and save the bytes of the message from the stream
networkStream.Read(objectBuffer, 0, objectBuffer.Length); ;
//I resize the array and just keep the bytes read
Array.Resize(ref objectBuffer, objectBuffer.Length);
//Deserialize and returns object
return convertObject.Deserialize(new MemoryStream(objectBuffer), types);
}
}
我终于找到问题所在了。基本上,如果使用该类型的构造函数创建实例,垃圾收集器将无法处理 XMLConverter
new XmlSerializer(type, otherTypes);
我使用了 Newtonsoft.Json 包中包含的 Json 序列化程序,而不是 class。它现在运行良好,而且速度快得多!
我正在尝试制作一个 C# 客户端/服务器程序,它可以通过序列化、反序列化和发送来在两个程序(在同一台计算机或不同计算机上)之间发送 类 TCP 但我不知道为什么程序使用了太多内存。执行几秒钟后,程序(客户端和服务器)都达到 100MB,并且使用的内存继续增加。我尝试同时使用 TCP 连接和命名管道,但问题仍然存在。所以我认为这是序列化和反序列化中的一个问题(也许),但我不知道。你有什么想法吗?
Class用于序列化和反序列化:
class ObjectSerializer {
public ObjectSerializer() { }
public MemoryStream Serialize(Object obj, Type[] types) {
MemoryStream memoryStream = new MemoryStream();
XmlSerializer xmlSerializer = new XmlSerializer(typeof(Object), types);
xmlSerializer.Serialize(memoryStream, obj);
return memoryStream;
}
public Object Deserialize(MemoryStream memoryStream, Type[] types) {
XmlSerializer xmlSerializer = new XmlSerializer(typeof(Object), types);
return (Object)xmlSerializer.Deserialize(memoryStream);
}
}
Class 包含用于发送和接收消息的方法以及 类:
class TCPMethods {
private NetworkStream networkStream;
private Type[] types;
//Constructor receiving a socket
public TCPMethods(Socket socket, Type[] types) {
this.networkStream = new NetworkStream(socket);
this.types = types;
}
//Constructor receiving a stream
public TCPMethods(NetworkStream networkStream, Type[] types) {
this.networkStream = networkStream;
this.types = types;
}
/*
*
* FUNCTIONS THAT SEND AND RECEIVE DATA THROUGH THE NETWORKSTREAM
*
*/
public void SendMessage(String message) {
//I serialize the message and send it
byte[] serializedMessage = Encoding.UTF8.GetBytes(message);
networkStream.Write(serializedMessage, 0, serializedMessage.Length);
}
public void SendObject(Object obj) {
ObjectSerializer convertObject = new ObjectSerializer();
//I call the class function to serialize the object and send it
byte[] serializedObject = convertObject.Serialize(obj, types).ToArray();
//Calculate and send the length of the byte array byte[] objectLenght = BitConverter.GetBytes(serializedObject.Length);
networkStream.Write(objectLenght, 0, objectLenght.Length);
networkStream.Write(serializedObject, 0, serializedObject.Length);
}
public String ReceiveMessage() {
//String in which the complete message will be inserted
String completeMessage = String.Empty;
//Byte array in which I save the message I am going to read from the stream
byte[] messageBuffer = new byte[512];
do {
//I read and save the bytes of the message from the stream
networkStream.Read(messageBuffer, 0, messageBuffer.Length);
//I convert to string and concatenate the message part
completeMessage += Encoding.UTF8.GetString(messageBuffer);
//I clear the byte buffer
messageBuffer = new byte[512];
//I repeat until I finish reading the message
} while (networkStream.DataAvailable);
return completeMessage;
}
public Object ReceiveObject() {
ObjectSerializer convertObject = new ObjectSerializer();
//I declare and read the variable which contains the length of the object
byte[] objectLenght = new byte[sizeof(int)];
networkStream.Read(objectLenght, 0, objectLenght.Length);
//Array in which the object will be saved
byte[] objectBuffer = new byte[BitConverter.ToInt32(objectLenght, 0)];
//I read and save the bytes of the message from the stream
networkStream.Read(objectBuffer, 0, objectBuffer.Length); ;
//I resize the array and just keep the bytes read
Array.Resize(ref objectBuffer, objectBuffer.Length);
//Deserialize and returns object
return convertObject.Deserialize(new MemoryStream(objectBuffer), types);
}
}
我终于找到问题所在了。基本上,如果使用该类型的构造函数创建实例,垃圾收集器将无法处理 XMLConverter
new XmlSerializer(type, otherTypes);
我使用了 Newtonsoft.Json 包中包含的 Json 序列化程序,而不是 class。它现在运行良好,而且速度快得多!