使用自定义序列化时出现OutOfMemory异常
本文关键字:OutOfMemory 异常 自定义 序列化 | 更新日期: 2023-09-27 18:13:08
在下面的代码中,我通过File对象的所有Block对象并执行基于bitconvert的序列化。在某些情况下,我有OutOfMemory异常。有什么方法可以优化它吗?
File.Serialze ();
public byte[] Serialize()
{
byte[] bytes = new byte[Blocks.Count * Block.Size];
for (int i = 0; i < Blocks.Count; i++)
{
Block block = Blocks[i];
Buffer.BlockCopy(block.Serialize(), 0, bytes, i * Block.Size, Block.Size);
}
return bytes;
}
Block.Serialize ()
public byte[] Serialize()
{
byte[] bytes = new byte[Size];
Buffer.BlockCopy(BitConverter.GetBytes(fid), 0, bytes, 0, sizeof(long));
Buffer.BlockCopy(BitConverter.GetBytes(bid), 0, bytes, sizeof(long), sizeof(long));
Buffer.BlockCopy(BitConverter.GetBytes(oid), 0, bytes, sizeof(long) * 2, sizeof(long));
Buffer.BlockCopy(BitConverter.GetBytes(iid), 0, bytes, sizeof(long) * 3, sizeof(long));
Buffer.BlockCopy(BitConverter.GetBytes(did), 0, bytes, sizeof(long) * 4, sizeof(long));
return bytes;
}
MemoryStream而不是byte[]和shift而不是BitConverter.GetBytes()方法:
File.Serialize ()
public MemoryStream Serialize()
{
MemoryStream fileMemoryStream = new MemoryStream(Blocks.Count * Block.Size);
foreach (Block block in Blocks)
{
using (MemoryStream blockMemoryStream = block.Serialize())
{
blockMemoryStream.WriteTo(fileMemoryStream);
}
}
return fileMemoryStream;
}
Block.Serialize ()
public MemoryStream Serialize()
{
MemoryStream memoryStream = new MemoryStream(Size);
memoryStream.Write(ConvertLongToByteArray(fid), 0, sizeof(long));
memoryStream.Write(ConvertLongToByteArray(bid), 0, sizeof(long));
memoryStream.Write(ConvertLongToByteArray(oid), 0, sizeof(long));
memoryStream.Write(ConvertLongToByteArray(iid), 0, sizeof(long));
memoryStream.Write(ConvertLongToByteArray(did), 0, sizeof(long));
return memoryStream;
}
private byte[] ConvertLongToByteArray(long number)
{
byte[] bytes = new byte[8];
bytes[7] = (byte)((number >> 56) & 0xFF);
bytes[6] = (byte)((number >> 48) & 0xFF);
bytes[5] = (byte)((number >> 40) & 0XFF);
bytes[4] = (byte)((number >> 32) & 0XFF);
bytes[3] = (byte)((number >> 24) & 0xFF);
bytes[2] = (byte)((number >> 16) & 0xFF);
bytes[1] = (byte)((number >> 8) & 0XFF);
bytes[0] = (byte)((number & 0XFF));
return bytes;
}
我要问的第一个问题是:什么是Count和Size ?如果这些(当相乘时)很大,那么是的,它会消耗内存。当然,序列化到一个大缓冲区总是会导致问题。最好看看序列化到流的技术,这将允许使用单个中等大小的缓冲区。在您的情况下,也许每个"块"可以单独序列化并刷新到流中,然后重用相同的中等大小的缓冲区。就我个人而言,我尽量避免引入不必要的"块"——另一种技术是序列化到缓冲流,并让它决定何时刷新到底层流。
最后,它总是让我失望,BitConverter想要创建byte[]。写这个API的人需要好好谈谈。适当的技术应该是让API接受缓冲区和偏移量,并向现有缓冲区写入数据。拨款少得多。我建议寻找不使用所有这些分配(诚然是短暂的)的方法。这对于int/long等来说很容易(你只需要使用shift操作),但是对于double等,你将需要不安全的代码或联合结构体。