Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/275.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 使用自定义序列化时OutOfMemory异常_C#_.net - Fatal编程技术网

C# 使用自定义序列化时OutOfMemory异常

C# 使用自定义序列化时OutOfMemory异常,c#,.net,C#,.net,在下面的代码中,我传递File对象的所有Block对象,并执行基于位转换的序列化。在某些情况下,我有OutOfMemory例外。有没有办法优化它 serialize() MemoryStream代替字节[],移位代替位转换器。GetBytes()方法: File.Serialize()文件 Block.Serialize() 我想问的第一个问题是:数量和大小是多少?如果这些(当乘以)是大的,那么是的,它将咀嚼记忆。当然,序列化到大缓冲区总是会引起问题。最好看一下序列化到流的技术,这样可以使用一个

在下面的代码中,我传递File对象的所有Block对象,并执行基于位转换的序列化。在某些情况下,我有OutOfMemory例外。有没有办法优化它

serialize()

MemoryStream代替字节[],移位代替位转换器。GetBytes()方法:

File.Serialize()文件

Block.Serialize()


我想问的第一个问题是:数量和大小是多少?如果这些(当乘以)是大的,那么是的,它将咀嚼记忆。当然,序列化到大缓冲区总是会引起问题。最好看一下序列化到流的技术,这样可以使用一个中等大小的缓冲区。在您的例子中,可能每个“块”可以单独序列化并刷新为一个流,然后重复使用相同大小的缓冲区。就我个人而言,我尽量避免引入不必要的“块”——另一种技术是序列化到缓冲流,让它决定何时刷新到底层流


最后,BitConverter想要创建字节[],这总是让我失望。不管是谁写的API都需要一个严厉的谈话。适当的技术应该是有一个API,它接受缓冲区和偏移量,并写入现有的缓冲区。拨款少得多。我建议寻找不需要所有这些(公认是短暂的)分配的写作方法。这对于int/long etc很容易(您只需要使用移位操作),但是对于double etc,您需要不安全的代码或联合结构。

我的第一个问题是:计数和大小是什么?如果这些(当乘以)是大的,那么是的,它将咀嚼记忆。当然,序列化到大缓冲区总是会引起问题。最好看一下序列化到流的技术,这样可以使用一个中等大小的缓冲区。在您的例子中,可能每个“块”可以单独序列化并刷新为一个流,然后重复使用相同大小的缓冲区。就我个人而言,我尽量避免引入不必要的“块”——另一种技术是序列化到缓冲流,让它决定何时刷新到底层流


最后,BitConverter想要创建字节[],这总是让我失望。不管是谁写的API都需要一个严厉的谈话。适当的技术应该是有一个API,它接受缓冲区和偏移量,并写入现有的缓冲区。拨款少得多。我建议寻找不需要所有这些(公认是短暂的)分配的写作方法。这对于int/long等来说很容易(您只需要使用移位操作),但是对于double等,您将需要不安全的代码或联合结构。

Marc Gravell,首先感谢您的回答,count*size是大int。我实现了MemoryStream而不是byte[],移位而不是BitConverter.GetBytes()。同样的问题再次出现。我已经添加了我的实现,也许我有一些问题。@eugeneK当它爆炸时堆栈跟踪是什么?如果数据很大,那么
MemoryStream
仍然会遇到同样的问题:您可能需要在内存之外进行序列化。您希望它是什么尺寸的?请尝试序列化为文件。file.Size在8k到20MBSystem.OutOfMemoryException之间:引发了“System.OutOfMemoryException”类型的异常。在Entities.File.Serialize()@eugeneK ok;您作为
容量
传递的值是多少?20MB对于内存工作来说并不是不合理的,但我怀疑您传递了更大的信息Arc Gravel,首先感谢您回答我,count*size是大整数。我实现了MemoryStream而不是byte[],移位而不是BitConverter.GetBytes()。同样的问题再次出现。我已经添加了我的实现,也许我有一些问题。@eugeneK当它爆炸时堆栈跟踪是什么?如果数据很大,那么
MemoryStream
仍然会遇到同样的问题:您可能需要在内存之外进行序列化。您希望它是什么尺寸的?请尝试序列化为文件。file.Size在8k到20MBSystem.OutOfMemoryException之间:引发了“System.OutOfMemoryException”类型的异常。在Entities.File.Serialize()@eugeneK ok;您作为
容量
传递的值是多少?20MB对于内存工作来说并不是不合理的,但我怀疑您传递了更大的内容
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;
}
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;
}
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;
}
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;
    }