在后台工作线程中序列化数据-内存不足异常

本文关键字:数据 内存不足 异常 序列化 后台 工作 线程 | 更新日期: 2023-09-27 18:17:34

我正在用binaryformatter序列化一个类,并使用deflateststream压缩数据。保存函数如下所示,从后台工作者调用:

public static void save(System system, String filePath) 
{
    //Make filestream
    FileStream fs = new FileStream(filePath, FileMode.Create);
    try 
    {
        //Serialize offerte
        BinaryFormatter bf = new BinaryFormatter();
        DeflateStream cs = new DeflateStream(fs, CompressionMode.Compress);
        bf.Serialize(cs, system);
        //Push through
        fs.Flush();
        cs.Flush();
        cs.Close();
    } 
    catch (Exception e) 
    {
        var mess = e.Message;
    } 
    finally 
    {
        //Close
        fs.Close();
    }
}

类有许多"用户"。100个用户需要10秒,文件大小为2MB。如果有1000个用户,则会出现内存不足异常(估计大小为16MB)。谁能在这里看到一个问题,或给出建议如何解决这个问题?(我首先想到的是后台线程上的时间导致了这一点,这需要很长时间。但是我有其他后台线程可以运行更长的时间

在后台工作线程中序列化数据-内存不足异常

您没有处理您的流,这可能是问题的一部分,建议:

public static void save(System system, String filePath) 
{
    //Make filestream
    using(FileStream fs = new FileStream(filePath, FileMode.Create))    
    {
        //Serialize offerte
        BinaryFormatter bf = new BinaryFormatter();
        using (DeflateStream cs = new DeflateStream(fs, CompressionMode.Compress)) {
           bf.Serialize(cs, system);
           //Push through
           fs.Flush();
           cs.Flush();
           cs.Close();
       }
    }     
}

这也消除了异常吞食,这可能是一件好事。

您使用几个类的对象来实现System。IDisposable

如果设计师实现了IDisposable,他会告诉你他可能会使用稀缺资源。您可能在垃圾收集器收集垃圾之前耗尽资源。

换句话说:当你使用一个实现System。一旦不再需要这个类,就应该调用Dispose()。如果您需要将类的资源用于其他事情,这尤其需要。

使用两个流类:FileStream和DeflateStream。它们都实现了IDisposable。如果你不调用Dispose(),垃圾收集器最终会调用,但是在此期间,这些流使用的资源是不可用的。

确保处置Disposable对象最简单的方法是使用using语句:

using (var myStream = new FileStream(...))
{
    ... // use myStream
}

当到达右括号时,myStream.Dispose()被调用,有效地释放它所使用的所有稀缺资源。

这适用于用于离开{…}块,包括break、return,甚至Exceptions。

因此,using是一个非常安全的方法:Dispose()将始终被调用。

顺便说一下:Dispose()也会注意到流被刷新和关闭,所以在using语句的末尾你不必Flush()和Close()。