Избегайте ошибки OutOfMemory, возникающей при использовании метода преобразования TransformerFactory при обработке большого XML - PullRequest
0 голосов
/ 24 сентября 2018

Когда я анализировал файлы дампа кучи с помощью инструмента анализатора памяти, он показывает код ниже (метод преобразования) в качестве основной причины ошибки OutOfMemory.Ниже приведен фрагмент кода:

public static String xmlToString(Node node) throws TransformerException
    {
            Source source = new DOMSource(node);
            StringWriter stringWriter = new StringWriter();
            Result result = new StreamResult(stringWriter);
            TransformerFactory factory = TransformerFactory.newInstance();
            Transformer transformer = factory.newTransformer();
            transformer.setOutputProperty(OutputKeys.METHOD, "xml");
            transformer.setOutputProperty(OutputKeys.INDENT,"yes");
            transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "3");
            transformer.transform(source, result);
            return stringWriter.getBuffer().toString();
    }

и трассировка стека инструмента анализатора памяти ниже:

at java.lang.OutOfMemoryError.<init>()V (OutOfMemoryError.java:48)
  at java.util.Arrays.copyOf([CI)[C (Arrays.java:3332)
  at java.lang.AbstractStringBuilder.ensureCapacityInternal(I)V (AbstractStringBuilder.java:124)
  at java.lang.AbstractStringBuilder.append(C)Ljava/lang/AbstractStringBuilder; (AbstractStringBuilder.java:649)
  at java.lang.StringBuffer.append(C)Ljava/lang/StringBuffer; (StringBuffer.java:381)
  at java.io.StringWriter.write(I)V (StringWriter.java:77)
  at org.apache.xml.serializer.ToStream.writeAttrString(Ljava/io/Writer;Ljava/lang/String;Ljava/lang/String;)V (ToStream.java:2155)
  at org.apache.xml.serializer.ToStream.processAttributes(Ljava/io/Writer;I)V (ToStream.java:2079)
  at org.apache.xml.serializer.ToStream.closeStartTag()V (ToStream.java:2623)
  at org.apache.xml.serializer.ToStream.characters([CII)V (ToStream.java:1410)
  at org.apache.xalan.transformer.TransformerIdentityImpl.characters([CII)V (TransformerIdentityImpl.java:1124)
  at org.apache.xml.serializer.TreeWalker.dispatachChars(Lorg/w3c/dom/Node;)V (TreeWalker.java:246)
  at org.apache.xml.serializer.TreeWalker.startNode(Lorg/w3c/dom/Node;)V (TreeWalker.java:416)
  at org.apache.xml.serializer.TreeWalker.traverse(Lorg/w3c/dom/Node;)V (TreeWalker.java:145)
  at org.apache.xalan.transformer.TransformerIdentityImpl.transform(Ljavax/xml/transform/Source;Ljavax/xml/transform/Result;)V (TransformerIdentityImpl.java:390)
  at com.something.StringUtil.xmlToString(Lorg/w3c/dom/Node;)Ljava/lang/String; (StringUtil.java:76)

Мы не можем изменить сигнатуру этого метода String xmlToString(Node node), так как этот метод используется во многих местах.

Вопрос здесь , есть ли способ изменить этот метод, чтобы избежать ошибки OOM?Этот метод должен занимать меньше памяти при обработке XML.То есть.или заменив transformer.transform(source, result) любым другим методом?или используя источник SAX или STAX вместо источника DOM внутри xmlToString(Node node) метода?

Используемый импорт:

org.w3c.dom.Node
javax.xml.transform.Source , Result, TransformerFactory
...