2016-05-12 13 views
0

Ich habe Probleme beim Freigeben des Speichers, den Saxon zum Laden der Datei in den Speicher verwendet. Dies ist eine verkleinerte Version des Codes haben wir:Sächsischer Speicher wird nicht freigegeben

Task newTask = Task.Run(() => 
{ 
    Processor processor = new Processor(); 
    DocumentBuilder documentBuilder = processor.NewDocumentBuilder(); 
    documentBuilder.IsLineNumbering = true; 
    documentBuilder.WhitespacePolicy = WhitespacePolicy.PreserveAll; 
    XQueryCompiler compiler = processor.NewXQueryCompiler(); 
    string query = BuildXqueryString(); 

    if (!String.IsNullOrEmpty(query)) 
    { 
     XQueryExecutable executable = compiler.Compile(query); 
     XQueryEvaluator evaluator = executable.Load(); 
     evaluator.ContextItem = documentBuilder.Build(xmlNode); 
     var evaluations = evaluator.Evaluate(); 
    } 
} 

Wir sind der Code in einem Task laufen, weil wir zugleich geschieht viele Auswertungen haben, viele von ihnen mit XML-Dateien bis zu 2 GB groß . Aus diesem Grund brauchen wir den von Saxon während der Ausführung der Build()-Methode verwendeten Speicher so schnell wie möglich, aber was passiert, ist, dass der Speicher vom Garbage Collector nicht vollständig zurückgewonnen wird. Nach jeder Auswertung steigt und sinkt die Speicherbelegung und wird nie vollständig freigegeben, so dass bei einigen dieser großen Auswertungen die Speicherauslastung auf den Maximalwert ansteigt. Ich habe versucht, die Dispose() Methode von Task anzurufen und alle Variablen auf null zu setzen, aber nichts scheint zu arbeiten. Irgendwelche Ideen, was passieren könnte?

Edit:

Vielen Dank für Ihre Antworten. Ich erkannte, dass das Problem tatsächlich nicht im sächsischen Code lag, sondern mit einem XmlDocument, das den Speicher nicht freigab. Entschuldigung für die Verwirrung.

+0

Haben die XQueryXXX-Klassen eine Verfügung? Das wären die, die du zerstören musst, um die Erinnerung freizugeben. Vielleicht kann auch ein GC.Collect() dabei helfen. – Gusman

+0

Welche Version von Saxon verwenden Sie? Ich habe dafür auf unserer Seite ein Bug-Problem erstellt: https://saxona.plan.io/issues/2746 Ist es möglich, dass Sie den vollständigen Code senden, damit wir das reproduzieren und weiter untersuchen können? Sie können den Code privat senden oder an das Fehlerproblem anhängen. – ond1

+0

Verwenden Sie Saxon-EE mit Bytecode-Generierung? Dies kann zu Speicherproblemen führen, da jedes Mal, wenn Sie eine Abfrage kompilieren, neue Klassen generiert werden und .NET normalerweise (um eine komplexe Geschichte zu vereinfachen) den von dynamisch geladenen Klassen belegten Speicher nicht freigibt. –

Antwort

0

Überprüfen Sie, ob eine der Klassen, von denen Instanzen innerhalb der Aufgabe verwendet werden, wegwerfbar sind. Sie könnten Ressourcen enthalten, bis dispose explizit aufgerufen wird (nachdem sie ihren Job erledigt haben). auch Kasse using Blöcke.

auch darauf hingewiesen, aus der official documentation:

Das erste, was die Anwendung tun muss, ist, einen Prozessor zu erstellen. Der Prozessor enthält Konfigurationsinformationen für Saxon und freigegebene Ressourcen wie den Namenspool und den Schemapool. Es ist möglich, mehrere Prozessoren gleichzeitig auszuführen, wenn erforderlich, aber es ist in der Regel mehr wirtschaftlich für alle sächsischen Prozesse innerhalb einer einzigen Anwendung den gleichen Prozessor zu verwenden.

Wie wäre es also mit der gleichen Prozessorinstanz für alle Ihre Aufgaben? Es könnte helfen, wenn es zwischengespeicherte Ressourcen verwendet.