2016-05-12 93 views
0

我有問題釋放內存薩克森用於將文件加載到內存中。這是代碼的簡化版本,我們有:撒克遜內存不被釋放

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(); 
    } 
} 

我們正在運行的代碼Task裏面,因爲我們有很多的評價,同時發生的,其中許多與XML文件高達2GB的。出於這個原因,我們需要Saxon在執行Build()方法時儘快使用的內存,但是發生的情況是內存沒有被垃圾回收器完全回收。在每次評估之後,內存使用量會升高並且永遠不會完全釋放,所以通過這些大的評估,內存使用量會上升到最大。我試過調用Dispose()方法Task,將所有變量設置爲null,但似乎沒有任何工作。任何想法可能發生什麼?

編輯:

謝謝大家的回答。我意識到這個問題實際上不是在撒克遜代碼中,而是用一個不釋放內存的XmlDocument。對困惑感到抱歉。

+0

XQueryXXX類是否有配置?那將是你爲了釋放內存而必須銷燬的那些。此外,也許一個GC.Collect()可以幫助這一點。 – Gusman

+0

您使用的是什麼版本的撒克遜?我在我們的網站上爲此創建了一個錯誤問題:https://saxonica.plan.io/issues/2746是否可以發送完整的代碼,以便我們可以重現此問題並進一步調查。您可以私密發送代碼或將其附加到錯誤問題。 – ond1

+0

您是否在使用帶有字節碼生成功能的Saxon-EE?這可能會導致內存問題,因爲每次編譯查詢時都會生成新的類,而.NET通常(爲了簡化複雜的故事)不會釋放由動態加載的類佔用的內存。 –

回答

0

檢查在任務內部使用哪些實例的類是一次性的,它們可以持有資源,直到明確調用dispose(在完成他們的工作之後)。還結賬using塊。

official documentation還注意到:

應用程序需要做的第一件事是創建一個處理器。 處理器保存Saxon的配置信息,並共享 資源,例如名稱池和模式池。如果需要,可以同時運行多個處理器,但通常對於單個應用程序中的所有撒克遜進程而言,更經濟的是使用 相同的處理器。

那麼如何使用相同的處理器實例爲您的所有任務?它可以幫助它防止使用緩存資源。