2015-02-03 1 views
0

Я не считаю, что я достаточно хорошо понимаю класс XsltTransformer, чтобы объяснить, почему метод f1 превосходит f2. Фактически, f1 заканчивается примерно через 40 секунд, потребляя от 750 до 1 ГБ памяти. Я ожидал, что f2 станет лучшим решением, но он никогда не заканчивается для того же длинного списка входных файлов. К тому моменту, когда я его убил, он обработал только около 1000 входных файлов, потребляя более 4 ГБ памяти.Is net.sf.saxon.s9api.XsltTransformer предназначен для одноразового использования?

import java.io.*; 
import javax.xml.transform.stream.StreamSource; 
import net.sf.saxon.s9api.*; 
public class foreachfile { 
    private static long f1 (Processor p, XsltExecutable e, Serializer ser, String args[]) { 
     long maxTotalMemory = 0; 
     Runtime rt = Runtime.getRuntime(); 
     for (int i=1; i<args.length; i++) { 
      String xmlfile = args[i]; 
      try { 
       XsltTransformer t = e.load(); 
       t.setDestination(ser); 
       t.setInitialContextNode(p.newDocumentBuilder().build(new StreamSource(new File(xmlfile)))); 
       t.transform(); 
       long tm = rt.totalMemory(); 
       if (tm > maxTotalMemory) 
        maxTotalMemory = tm; 
      } catch (Throwable ex) { 
       System.err.println(ex); 
      } 
     } 
     return maxTotalMemory; 
    } 
    private static long f2 (Processor p, XsltExecutable e, Serializer ser, String args[]) { 
     long maxTotalMemory = 0; 
     Runtime rt = Runtime.getRuntime(); 
     XsltTransformer t = e.load(); 
     t.setDestination(ser); 
     for (int i=1; i<args.length; i++) { 
      String xmlfile = args[i]; 
      try { 
       t.setInitialContextNode(p.newDocumentBuilder().build(new StreamSource(new File(xmlfile)))); 
       t.transform(); 
       long tm = rt.totalMemory(); 
       if (tm > maxTotalMemory) 
        maxTotalMemory = tm; 
      } catch (Throwable ex) { 
       System.err.println(ex); 
      } 
     } 
     return maxTotalMemory; 
    } 
    public static void main (String args[]) throws SaxonApiException, Exception { 
     String usecase = System.getProperty("xslt.usecase"); 
     int uc = Integer.parseInt(usecase); 
     String xslfile = args[0]; 
     Processor p = new Processor(true); 
     XsltCompiler c = p.newXsltCompiler(); 
     XsltExecutable e = c.compile(new StreamSource(new File(xslfile))); 
     Serializer ser = new Serializer(); 
     ser.setOutputStream(System.out); 
     long maxTotalMemory = uc == 1 ? f1(p, e, ser, args) : f2(p, e, ser, args); 
     System.err.println(String.format("Max total memory was %d", maxTotalMemory)); 
    } 
} 

ответ

1

Обычно я рекомендую использовать новый XsltTransformer для каждого преобразования. Тем не менее, класс можно повторно использовать повторно (вы можете выполнять несколько преобразований один за другим, но не одновременно). XsltTransformer сохраняет определенные ресурсы в памяти, если они нужны снова: в частности, все документы читаются с использованием функций doc() или document(). Это может быть полезно, например, если вы хотите преобразовать один набор входных документов в пять разных форматов вывода в рамках рабочего процесса публикации. Но если это повторное использование ресурсов не дает вам никаких преимуществ, оно просто накладывает затраты на использование памяти, чего вы можете избежать, создавая каждый новый трансформатор. То же самое происходит, если вы используете интерфейс JAXP.