ORM として Fluent NHibernate を使用していますが、メモリ リークのエラーが発生します。
同じ PC で異なる Web ブラウザからホームページにアクセスしようとすると、CPU 使用率は 2 ~ 3% ですが、メモリ使用率は 80 ~ 90% になり、Web サイトの速度が低下し、システムがハングします。Web サイトを再度実行するには、タスク マネージャーからプロセスを終了する必要があります。もう1つ、ブラウザからアクセスするとメモリが使用されますが、閉じると、すべてのリソース(そのメモリ)が解放されません。
私はこの方法でウェブサイトのアーキテクチャを作成しました:-
- 静的メンバーとしてリポジトリ オブジェクトを作成したクラス「ParentObject」を作成しました。
- 私が作成したすべてのエンティティは、「ParentObject」クラスから継承されています。
「Controller」クラスから継承したもう1つのクラスBaseControllerを作成し、Baseクラスでこのコードを使用しました:-
protected override void OnActionExecuting(ActionExecutingContext filterContext) { base.OnActionExecuting(filterContext); EdustructRepository Repository; // My Repository Class where I have written logic for opening and closing Save and Update Session.I have mentioned my this logic below if (Session["Repository"] != null) { Repository = (EdustructRepository)Session["Repository"]; if (!Repository.GetSession().Transaction.IsActive) Repository.GetSession().Clear(); } else { Repository = new EdustructRepository(typeof(ActivityType), FluentNhibernateRepository.DataBaseTypes.MySql); Session["Repository"] = Repository; } if (ParentObject._repository == null) { ParentObject._repository = new EdustructRepository(); // Here i have set the ParentObject's static variable "_repository" by this i have accessed repository in all my Entities . } }
そして、すべてのコントローラーを BaseController クラスで継承しました。これにより、アクションがヒットするたびに「_repository」オブジェクトを取得できました。
私のセッション管理ロジック
public class EdustructRepository : NHibernetRepository
{
public void Save<T>(T item, bool clearSession)
{
if (typeof(T).GetProperty("Created_at").GetValue(item, null).ToString() == DateTime.MinValue.ToString())
{
typeof(T).GetProperty("Created_at").SetValue(item, MySqlDateTime.CurrentDateTime(), null);
}
typeof(T).GetProperty("Updated_at").SetValue(item, MySqlDateTime.CurrentDateTime(), null);
base.CheckAndOpenSession();
using (var transaction = base.GetSession().BeginTransaction())
{
try
{
base.GetSession().SaveOrUpdate(item);
transaction.Commit();
if (clearSession)
{
Session.Clear();
}
}
catch
{
base.Evict(item);
base.Clear();
throw;
}
}
//base.Save<T>(item, clearSession);
}
public void Save<T>(T item)
{
Save<T>(item, false);
}
}
public class NHibernetRepository : IDisposable
{
public static ISessionFactory _SessionFactory = null;
protected ISession Session = null;
private ISessionFactory CreateSessionFactory()
{
return Fluently.Configure()
.Database(MySQLConfiguration.Standard.ConnectionString(c => c.FromConnectionStringWithKey("DBConnectionString")))
.Mappings(m =>m.FluentMappings.AddFromAssembly((Assembly.Load("Edustruct.Social.DataModel"))).Conventions.Add<CascadeConvention>())
.ExposeConfiguration(cfg => cfg.SetProperty(NHibernate.Cfg.Environment.CurrentSessionContextClass,"web"))
.BuildSessionFactory();
}
protected void CheckAndOpenSession()
{
if (_SessionFactory == null)
{
_SessionFactory = CreateSessionFactory();
}
if (Session == null)
{
Session = _SessionFactory.OpenSession();
Session.FlushMode = FlushMode.Auto;
}
if (!Session.IsOpen)
Session = _SessionFactory.OpenSession();
else if (!Session.IsConnected)
Session.Reconnect();
}
}
注: レポジトリのセッションを閉じていません。これは、遅延初期化を使用しており、ビューでも使用しているためです。ここでセッションを閉じると、「セッションが見つかりません」というエラーが表示されます。
これが私のウェブサイトの流れを作った方法です。このコードを確認して、このエラーが発生する理由を教えてください。
よろしくお願いします。