我在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类的特定实例的根图:
http://i.stack.imgur.com/U9ukC.png
正如您在DoQuery和List之间看到的那样,没有字段名称。
起初我认为问题出在结果转换器上,但即使在关闭之后,我仍然看到原始值的内存泄漏为string []。
我做错了什么?为什么EntityFields实例在会话中保留?
答案 0 :(得分:0)
发现问题,我在其他地方有一个错误导致实体的请求非常快速,从而导致服务器上的内存过载。