【问题标题】:Memory leak with non nhibernate entities非休眠实体的内存泄漏
【发布时间】:2013-12-16 23:54:28
【问题描述】:

我在 NHibernate 和 ActiveRecord 中遇到了一种奇怪的内存泄漏情况。 我设计了一个系统来加载特定的实体列,以便将其转换为平面订单并通过网络传输它们。它托管在 IIS 中,用作多个销售点设备的中心点。

该系统适用于非常大量的实体,一次可达数百万。

它的工作原理基本上是确定实体元数据中需要哪些列,将其提取到投影并使用结果转换器执行查询。

我不确定发生了什么变化,但我遇到了一种情况,即我看到转换结果的内存泄漏,分析器告诉我实体被保存在类 Loader 的某个 List 中方法 DoQuery。我在那种方法中找不到任何会导致他们被关押的东西。

这是我用来获取行值的函数,它也用于加载我拥有的其他普通 NHibernate 实体:

    public static IList GetResultsForCriteria(DetachedCriteria crit, int? maxResults,TransactionLockModeEnum transactionLockMode)
    {
        ISessionFactoryHolder holder = ActiveRecordMediator.GetSessionFactoryHolder();

        ISession session = holder.CreateSession(typeof(object));
        session.FlushMode = FlushMode.Never;

        ITransaction transaction = null;

        if (transactionLockMode == TransactionLockModeEnum.NonLocking)
        {
            transaction = session.BeginTransaction(IsolationLevel.ReadUncommitted);
        }

        ICriteria executableCriteria = crit.GetExecutableCriteria(session);

        if (maxResults.HasValue)
        {
            executableCriteria.SetMaxResults(maxResults.Value);
        }

        IList results;

        try
        {
            if (session.Connection.State == ConnectionState.Closed)
            {
                session.Connection.Open();
            }

            results = executableCriteria.List();

            if (transaction != null)
            {
                transaction.Commit();
            }

            ConnectionMonitor.AddConnection(session.Connection);
        }
        finally
        {
            holder.ReleaseSession(session);
        }

        return results;            
    }

这是我用来将原始值转换为具有属性名称和值的字典的转换器:

class EntityRetrieverResultTransform : IResultTransformer
{
    public object TransformTuple(object[] tuple, string[] aliases)
    {
        EntityFields fields = new EntityFields();

        for (int i = 0; i < tuple.Length; i++)
        {
            string aliasName = aliases[i].Replace("[","").Replace("]","");
            fields.Add(aliasName,tuple[i]);
        }

        return fields;
    }

    public IList TransformList(IList collection)
    {
        return collection;
    }
}

EntityFields 类是一个简单的类:

public class EntityFields : Dictionary<string,object>
{
}

这是来自分析器的根图,用于 EntityFields 类的特定实例:

http://i.stack.imgur.com/U9ukC.png

正如您在 DoQuery 和 List 之间看到的那样,没有字段名称。

一开始我以为问题出在结果转换器上,但即使去掉它,我仍然看到原始值作为 string[] 的内存泄漏。

我做错了什么?为什么 EntityFields 实例被保存在会话中?

【问题讨论】:

    标签: nhibernate activerecord memory-leaks


    【解决方案1】:

    发现了问题,我在其他地方遇到了一个错误,导致对实体的请求序列非常快,从而导致服务器内存过载。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-09-26
      • 2012-09-09
      • 2012-01-30
      相关资源
      最近更新 更多