非nhibernate实体的内存泄漏

非nhibernate实体的内存泄漏,nhibernate,activerecord,memory-leaks,Nhibernate,Activerecord,Memory Leaks,我在NHibernate和ActiveRecord中遇到了一个奇怪的内存泄漏情况。 我设计了一个系统来加载实体的特定列,以便将其转换为平面顺序并通过网络传输。它托管在IIS中,作为多个销售点设备的中心点 这个系统对于大量的实体(一次多达数百万个)运行良好 它基本上是通过确定实体元数据中需要哪些列、将其提取到投影并使用结果转换器执行查询来工作的 我不确定发生了什么变化,但我遇到了这样一种情况:我看到转换结果的内存泄漏,探查器告诉我实体被保存在DoQuery方法的类加载器中的某个列表中。我在那种方法

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

这个系统对于大量的实体(一次多达数百万个)运行良好

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

我不确定发生了什么变化,但我遇到了这样一种情况:我看到转换结果的内存泄漏,探查器告诉我实体被保存在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;
    }
}
类EntityRetrieverResultTransform:IResultTransformer
{
公共对象转换元组(对象[]元组,字符串[]别名)
{
EntityFields=新的EntityFields();
for(int i=0;i
类EntityFields是一个简单的类:

public class EntityFields : Dictionary<string,object>
{
}
公共类EntityFields:字典
{
}
下面是探查器中类EntityFields特定实例的根图:

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

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


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

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