内存不足50MB文件序列化并保存

时间:2014-08-14 21:38:36

标签: c# serialization unity3d out-of-memory filestream

我在内存中创建了一个200MB的对象数组,使用此方法将此数组保存到文件时会导致内存不足问题。我将阵列分成几个部分(每个部分大约50MB),但是,在保存时它仍然会导致内存问题。

文件管理器类:

public void WriteStream(string saveLocation, object o)
{
    FileStream fs = new FileStream(saveLocation, FileMode.Create);
    BinaryFormatter formatter = new BinaryFormatter();
    formatter.Serialize(fs, o);
    fs.Close();
}

来自另一个班级:

    FileManager fm = new FileManager();
    for(int i = 0; i < tileData.Length; i++)
    {
        string path = appDataFolder + @"\"+levelName+"layer"+i.ToString()+".dat";
        fm.WriteStream(path, tileData[i]);
    }

正在保存的可序列化对象(上面的tileData):

[Serializable]
public class TileMapData : ISerializable
{
    public int layer;
    public int width;
    public int height;
    public int[,] type;
    public int[,] bitmask;
    public int[,] status;
    public int[,] groupID;
    public void GetObjectData(SerializationInfo info, StreamingContext context)
    { 
      //omitted to save space
    }

    public TileMapData(SerializationInfo info, StreamingContext context)
    { 
       //omitted to save space
    }
}

什么是克服这个问题的方法?

这次使用StreamWriter的第二次尝试,仍然是同样的问题。

     public void BinaryWriteSave(string saveLocation, object o)
    {
        byte[] byteArray = ObjectToByteArray(o);
        using (BinaryWriter bw = new BinaryWriter(File.Open(saveLocation, FileMode.Create)))
        {
            bw.Write(byteArray);
        }
    }

enter image description here

2 个答案:

答案 0 :(得分:0)

我建议使用内存映射字段进行此类操作。

答案 1 :(得分:0)

不是答案,但评论时间太长了。

该异常表明你的第三方库,我认为是图标图像中的unity3d,实际上内存不足,无法分配864兆字节。这不是.Net例外; .Net和BinaryFormatter永远不会抛出内存不足的异常,FileStream缓冲区永远不会太大。

所以,一些想法:

  1. 找出抛出非托管异常的确切回溯。当通过“Debug”抛出所有异常时,可以通过在Visual Studio中打破来实现这一点 - &gt; “异常”并在“异常”对话框中选中“抛出”: enter image description here 然后启用非托管调试,如下所述:How to: Enable Debugging of Unmanaged Code(您可能只需要enable breaking on SEHException when thrown。)一旦您知道导致内存使用的对象类型和回溯,您就可以更新您的问题使用该信息并搜索现有答案。

  2. 当序列化为二进制时,unity3d似乎是将序列化的代理数据结构分配给比其正常数据结构大得多的代理数据结构。上面的追溯可能会让你知道它是什么。有什么理由需要这样做吗?例如,您是否将稀疏矩阵表示转换为非稀疏矩阵表示以进行序列化?如果是这样,请尽量不这样做。

  3. 如果unity3d确实需要分配那么多内存,请考虑将数据分成小块并将每个小块分别存储到文件中。本文提供了以下说明:Serializing lots of different objects into a single file

  4. 或者,也许你的数据库在某种程度上是腐败的,也许在unity3d不允许的情况下包含循环引用。你可以做的是尝试通过二分法来识别坏数据:尝试序列化一半的数据,然后是第二个。如果只有一个失败,那么腐败可能就在那一半。重复,直到找到损坏的物体。