加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

c# – MemoryStream泄漏

发布时间:2020-12-15 08:28:34 所属栏目:百科 来源:网络整理
导读:谁能告诉我们下面这段代码有什么问题? 我们这里有一个对象序列化程序,它应该返回传递给它的任何对象的 XML字符串. 我们一直在讨论这个问题,因为我们有一个多次调用这个程序的程序,我们看到我们的内存使用量一直很高(甚至在程序完成后仍然存在)…我们已经完
谁能告诉我们下面这段代码有什么问题?
我们这里有一个对象序列化程序,它应该返回传递给它的任何对象的 XML字符串.

我们一直在讨论这个问题,因为我们有一个多次调用这个程序的程序,我们看到我们的内存使用量一直很高(甚至在程序完成后仍然存在)…我们已经完成了搜索但是徒劳无功. stream对象在一个“using”语句中,所以我们认为这应该是自己处理的..请帮忙.

public static string ToXML(this IMessage m)
    {          
        try
        {
            var serializer = SerializerFactory.Create(m.GetType());
            using (var stream = new MemoryStream())
            {
                serializer.Serialize(new[] { m },stream);
                stream.Position = 0;
                var s = Encoding.ASCII.GetString(stream.ToArray());
                return s;
            }
        }
        catch (Exception e)
        {
            return string.Format("Message unserializable: {0}",e.Message);
        }
    }

btw SerializerFactory看起来像这样:

public class SerializerFactory
{
    public static IMessageSerializer Create(Type t)
    {
        var types = new List<Type> { t };
        var mapper = new MessageMapper();
        mapper.Initialize(types);
        var serializer = new XmlMessageSerializer(mapper);

        serializer.Initialize(types);

        return serializer;
    }
}

解决方法

这段代码没有什么大错;请注意,在MemoryStream上使用本质上是一个无操作,因为它只有托管资源,托管资源是GC的域; GC收集一些内存是不合理的,这是正常的,所以我不会过分强调 – 或者:如果有问题,可能不是这个.

但有一点是,您可以在编码步骤中避免使用缓冲区:

var s = Encoding.ASCII.GetString(stream.GetBuffer(),(int)stream.Length);

实际上,我很想在默认情况下使用UTF8,而不是ASCII.

最后一个想法:你的SerializerFactory本身是在做什么泄漏吗?例如,您是否通过任何更复杂的构造函数创建新的XmlSerializer(…)?最简单的形式:

new XmlSerializer(typeof(SomeType));

很好 – 它在内部缓存每个类型的内部/实际序列化程序,并为这样创建的每个XmlSerializer实例重用它.但是,它不会为更复杂的构造函数重载执行此缓存:它每次都会创建并加载新的动态程序集.并且以这种方式加载的程序集永远不会被卸载 – 所以是的,这可能会导致内存泄漏.我非常希望看到如何创建序列化程序实例,看看这是否是实际问题.请注意,通过在工厂中创建自己的序列化程序缓存,这种情况通常很容易解决:

public class SerializerFactory
{
    // hashtable has better threading semantics than dictionary,honest!
    private static readonly Hashtable cache = new Hashtable();
    public static IMessageSerializer Create(Type t)
    {
        var found = (IMessageSerializer)cache[t];
        if(found != null) return found;

        lock(cache)
        {   // double-checked
            found = (IMessageSerializer)cache[t];
            if(found != null) return found;

            var types = new List<Type> { t };
            var mapper = new MessageMapper();
            mapper.Initialize(types);
            var serializer = new XmlMessageSerializer(mapper);

            serializer.Initialize(types);

            cache[t] = serializer;

            return serializer;
        }
    }
}

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读