内存泄漏与非nhibernate实体

时间:2013-12-16 13:38:53

标签: nhibernate activerecord memory-leaks

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

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

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

我不确定是什么改变了,但是我遇到了一种情况,我看到转换结果的内存泄漏,其中探查器告诉我实体被保存在类Loader中的某个列表中方法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类的特定实例的根图:

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

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

起初我认为问题出在结果转换器上,但即使在关闭之后,我仍然看到原始值的内存泄漏为string []。

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

1 个答案:

答案 0 :(得分:0)

发现问题,我在其他地方有一个错误导致实体的请求非常快速,从而导致服务器上的内存过载。