spec servlet files example java xml memory parsing out-of-memory

java - servlet - Big XML file y OutOfMemoryError



upload file jsp servlet example (8)

Estoy tratando de analizar un archivo XML de hasta 500 mb en Java. Traté de usar SAX pero me da este error java.lang.OutOfMemoryError: espacio de pila de Java en com.sun.org.apache.xerces.internal.util.XMLStringBuffer.append (Fuente desconocida) ¿Me pueden ayudar? Muchas gracias. PS Pequeños archivos XML funcionan bien


Lo más probable es que no esté utilizando SAX correctamente, o su aplicación no es adecuada para el procesamiento de flujo.

El objetivo de SAX es evitar mantener toda la estructura XML en la memoria, pero eso solo es posible si puede procesar el XML en pequeños fragmentos sin guardar demasiado contexto, y si el resultado del procesamiento es mucho más pequeño que el XML procesado ( para que no use demasiada memoria) o puede pasarse a un destinatario o escribirse en el disco continuamente.

Editar: también es posible que simplemente tenga una pérdida de memoria, es decir, que está reteniendo datos que ya no necesita, evitando que se recolecte la basura. Si usa cualquier Listas, Mapas o Conjuntos para procesar el XML, asegúrese de que todo lo que agregue al procesar un fragmento de XML se elimine antes de comenzar con el próximo fragmento.


Puede intentar aumentar el tamaño del almacenamiento dinámico de Java especificando, p. Ej.

java -Xmx1024M MyClass

en la línea de comandos (o el valor que sea adecuado para el tamaño de su documento).



Supongamos que tiene la siguiente estructura XML:

<?xml version="1.0"?> <list> <item> <name>Alpha</name> <age>10</age> </item> <item> <name>Beta</name> <age>20</age> </item> <!-- many many items --> </list>

Y quieres obtener todos los <item> s

clase pública Item {String name; Edad de cadena; }

Su controlador SAX se verá así

public class MyHandler extends DefaultHandler { Item current=null; StringBuilder content=null; @Override public void startElement(String uri, String localName, String name, Attributes attributes) throws SAXException { if( name.equals("item") { current= new Item(); } else if(name.equals("name") || name.equals("age")) { content= new StringBuilder(); } } @Override public void endElement(String uri, String localName, String name) throws SAXException { if(name.equals("item")) { //DO SOMETHING WITH current System.out.println(current); current=null; } else if(name.equals("name")) { current.name= content.toString(); } else if(name.equals("age")) { current.age= content.toString(); } content=null; } @Override public void characters(char[] ch, int start, int length) throws SAXException { if(content!=null) { content.append(ch,start,length); } } }

Como puede ver, el ''contenido'' solo se memoriza entre las etiquetas ''edad'' y ''nombre''.




Puede usar el ejemplo de código aquí . Es una solución escalable que puede procesar archivos xml de gran tamaño.


Es posible que desee comprobar ScaleDOM, que permite analizar archivos XML de gran tamaño: https://github.com/whummer/scaleDOM

ScaleDOM tiene una huella de memoria pequeña debido a la carga diferida de los nodos XML. Solo conserva una parte del documento XML en la memoria y vuelve a cargar los nodos desde el archivo fuente cuando es necesario.