Ich debugge einen vorhandenen Windows-Dienst (geschrieben in C#), der alle paar Monate manuell neu gestartet werden muss, da es Speicher speichert.Windows-Dienst mit NHibernate erhöht benutzter Speicher
Der Service ist nicht sehr kompliziert. Er fordert eine JSON-Datei von einem externen Server an, der Produkte enthält. Als nächstes analysiert es diese JSON-Datei in eine Liste von Produkten. Für jedes dieser Produkte wird geprüft, ob dieses Produkt bereits in der Datenbank vorhanden ist. Wenn nicht, wird es hinzugefügt, wenn es existiert, werden die Eigenschaften aktualisiert.
Die Datenbank ist eine PostgreSQL-Datenbank und wir verwenden NHibernate v3.2.0 als ORM.
Ich habe JetBrains DotMemory wurde mit dem Service profilieren, wenn es läuft:
der Dienst gestartet wird und nach 30s es seine Arbeit beginnt zu tun. SnapShot # 1 wird vor dem ersten Lauf erstellt. Snapshot # 6 wurde nach dem 5. Lauf erstellt. Die anderen Snapshots werden auch nach einem Lauf erstellt. Wie Sie nach jedem Lauf sehen können, erhöht sich die Anzahl der Objekte um ca. 60k und der verwendete Speicher steigt mit ein paar MB nach jedem Lauf.
Bei genauerer Betrachtung Snapshot # 6, zeigt die beibehaltene Größe meist von NHibernate Sitzungsobjekte verwendet wird:
Hier ist mein OnStart Code:
try
{
// Trying to fix certificate errors:
ServicePointManager.ServerCertificateValidationCallback += delegate
{
_logger.Debug("Cert validation work around");
return true;
};
_timer = new Timer(_interval)
{
AutoReset = false // makes it fire only once, restart when work is done to prevent multiple runs
};
_timer.Elapsed += DoServiceWork;
_timer.Start();
}
catch (Exception ex)
{
_logger.Error("Exception in OnStart: " + ex.Message, ex);
}
Und mein DoServiceWork:
try
{
// Call execute
var processor = new SAPProductProcessor();
processor.Execute();
}
catch (Exception ex)
{
_logger.Error("Error in DoServiceWork", ex);
}
finally
{
// Next round:
_timer.Start();
}
In SAPProductProcessor Ich verwende zwei db-Aufrufe Beide in einer Schleife. I Schleife durch alle Produkte aus der JSON-Datei und prüfen, ob das Produkt bereits in der Tabelle ist den Produktcode:
ProductDto dto;
using (var session = SessionFactory.OpenSession())
{
using (var transaction = session.BeginTransaction(IsolationLevel.ReadCommitted))
{
var criteria = session.CreateCriteria<ProductDto>();
criteria.Add(Restrictions.Eq("Code", code));
dto = criteria.UniqueResult<ProductDto>();
transaction.Commit();
}
}
return dto;
Und wenn der productDto I speichert sie aktualisiert werden:
using (var session = SessionFactory.OpenSession())
{
using (var transaction = session.BeginTransaction(IsolationLevel.ReadCommitted))
{
session.SaveOrUpdate(item);
transaction.Commit();
}
}
Ich bin nicht sicher, wie man den Code oben ändert, um den Speicher und die Anzahl der Objekte zu erhöhen.
Ich habe bereits versucht var session = SessionFactory.GetCurrentSession();
anstelle von using (var session = SessionFactory.OpenSession())
, aber das hat nicht die Erhöhung des Speichers zu stoppen.
aktualisieren
Im Konstruktor meiner Datenzugriffsklasse MultiSessionFactoryProvider sessionFactoryProvider
injiziert. Und die Basisklasse wird mit : base(sessionFactoryProvider.GetFactory("data"))
aufgerufen. Diese Basisklasse hat eine Methode BeginSession
:
ISession session = _sessionFactory.GetCurrentSession();
if (session == null)
{
session = _sessionFactory.OpenSession();
ThreadLocalSessionContext.Bind(session);
}
Und ein EndSession
:
ISession session = ThreadLocalSessionContext.Unbind(_sessionFactory);
if (session != null)
{
session.Close();
}
In meiner Datenzugriffsklasse I base.BeginSession
zu Beginn anrufen und base.EndSession
an dann zu beenden.
ist Ihr 'DoServiceWork' ein Singleton? Ich sehe, dass "SAPProductProcessor" jedes Mal erstellt wird. Vielleicht ist das etwas zum Anschauen? –
Die SessionFactory ist eine Eigenschaft? Wo wird die SessionFactory erstellt? Es sollte nur einmal für einen Prozess (oder AppDomain) erstellt werden. –
Öffnen Sie den Vergleich, öffnen Sie alle neuen Objekte und schauen Sie, welche Objekte gehalten werden und warum. –