非nhibernate实体的内存泄漏
我在NHibernate和ActiveRecord中遇到了一个奇怪的内存泄漏情况。 我设计了一个系统来加载实体的特定列,以便将其转换为平面顺序并通过网络传输。它托管在IIS中,作为多个销售点设备的中心点 这个系统对于大量的实体(一次多达数百万个)运行良好 它基本上是通过确定实体元数据中需要哪些列、将其提取到投影并使用结果转换器执行查询来工作的 我不确定发生了什么变化,但我遇到了这样一种情况:我看到转换结果的内存泄漏,探查器告诉我实体被保存在DoQuery方法的类加载器中的某个列表中。我在那种方法中找不到任何会导致他们被拘留的东西 这是我用来获取行值的函数,它还用于加载我拥有的其他普通NHibernate实体:非nhibernate实体的内存泄漏,nhibernate,activerecord,memory-leaks,Nhibernate,Activerecord,Memory Leaks,我在NHibernate和ActiveRecord中遇到了一个奇怪的内存泄漏情况。 我设计了一个系统来加载实体的特定列,以便将其转换为平面顺序并通过网络传输。它托管在IIS中,作为多个销售点设备的中心点 这个系统对于大量的实体(一次多达数百万个)运行良好 它基本上是通过确定实体元数据中需要哪些列、将其提取到投影并使用结果转换器执行查询来工作的 我不确定发生了什么变化,但我遇到了这样一种情况:我看到转换结果的内存泄漏,探查器告诉我实体被保存在DoQuery方法的类加载器中的某个列表中。我在那种方法
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,导致对实体的请求序列非常快速,从而导致服务器内存过载