2009-02-02 6 views
2

J'essaye d'analyser un fichier XML jusqu'à 500 Mo en Java. J'ai essayé d'utiliser SAX mais il me donne cette erreur java.lang.OutOfMemoryError: Java heap space at com.sun.org.apache.xerces.internal.util.XMLStringBuffer.append (Source inconnue) Pouvez-vous m'aider? Merci beaucoup. P.S. fichiers XML petits fonctionne très bienBig fichier XML et OutOfMemoryError

+0

Je suis également intéressé par ce que vous stockez dans un fichier XML de 500 Mo! –

+0

Votre code XML contient-il de très grandes quantités de texte (10 millions de caractères, par exemple) sans éléments intermédiaires? – bendin

+0

Je ne sais pas pourquoi ... est un projet d'école. Le fichier est ici http://dblp.uni-trier.de/xml/. – user61652

Répondre

3

Vous pouvez essayer d'augmenter la taille du tas Java en spécifiant par exemple

java -Xmx1024M MyClass 

sur la ligne de commande (ou quelle que soit la valeur adaptée à la taille de votre document).

11

Vous n'utilisez probablement pas SAX correctement, ou votre application n'est pas adaptée au traitement de flux. Le but de SAX est d'éviter de garder toute la structure XML en mémoire, mais cela n'est possible que si vous pouvez traiter le XML en petits morceaux sans garder beaucoup de contexte, et si le résultat du traitement est beaucoup plus petit que le XML traité (de sorte qu'il n'utilise pas trop de mémoire non plus) ou peut lui-même être transmis à un destinataire ou écrit sur le disque en continu.

Edit: Il est également possible que vous avez simplement une fuite de mémoire, à savoir que vous tenez sur les données que vous n'avez plus besoin, l'empêchant de se ramasse-miettes. Si vous utilisez des listes, des cartes ou des ensembles pour traiter le code XML, assurez-vous que tout ce que vous y ajoutez lors du traitement d'un segment de code XML est supprimé avant de commencer le segment suivant.

+0

AbsolutellY correct. Je pourrais analyser plus de 2 Go de fichier XML avec SAX. – takacsot

1

Supposons que vous avez la structure XML suivante:

<?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> 

Et vous voulez obtenir toutes les <article> de

public class Article { Nom de la chaîne; Âge de la corde; }

Votre gestionnaire SAX ressemblera à ceci

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

} 

Comme vous pouvez le voir, le « contenu » est mémorisé seulement entre les balises « âge » et « nom ».

1

Vous pouvez consulter ScaleDOM, qui permet d'analyser de très gros fichiers XML: https://github.com/whummer/scaleDOM

ScaleDOM a une faible empreinte mémoire due au chargement paresseux des noeuds XML. Il ne conserve en mémoire qu'une partie du document XML et recharge les nœuds à partir du fichier source si nécessaire.