2010-08-02 19 views
0

J'ai besoin d'utiliser JDOM pour générer des fichiers XML, ce qui pourrait être assez gros. Je me demande combien espace mémoire supplémentaire JDOM a besoin d'autres que les données, principalement des chaînes, qui est déjà dans la mémoire. J'ai écrit un programme simple à tester et il s'est avéré que les frais généraux sont environ deux fois plus élevés que le contenu XML.De combien de mémoire "overhead" JDOM a-t-il besoin pour générer des fichiers XML?

Est-ce que quelqu'un sait pourquoi JDOM a besoin de beaucoup plus de mémoire et s'il y a moyen de l'optimiser? Les objets JDOM ne devraient-ils pas garder une référence aux chaînes existantes?

Voici le programme que j'utilisé pour tester:

public class TestJdomMemoryOverhead { 
    private static Runtime runtime = Runtime.getRuntime(); 

    public static void gc() { 
     // Try to give the JVM some hints to run garbage collection 
     for (int i = 0; i < 5; i++) { 
      runtime.runFinalization(); 
      runtime.gc(); 
      Thread.currentThread().yield(); 
     } 
    } 

    public static void generateXml(List<String> filenames) throws IOException { 
     // generate a simple XML file by these file names. It looks like: 
     // <?xml version="1.0" encoding="UTF-8"?> 
     // <files> 
     // <f n="aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" /> 
     // <f n="aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" /> 
     // <f n="aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" /> 
     // .... 
     // .... 
     // </files> 
     Element filesElem = new Element("files"); 
     Document doc = new Document(filesElem); 
     for (String name : filenames) { 
      Element fileElem = new Element("f"); 
      fileElem.setAttribute("n", name); 
      filesElem.addContent(fileElem); 
     } 
     gc(); 
     System.out.println("After generating JDOM objects: " + (runtime.totalMemory() - runtime.freeMemory()) + " bytes"); 
     XMLOutputter outputter = new XMLOutputter(Format.getPrettyFormat()); 
     BufferedWriter writer = new BufferedWriter(new FileWriter("test.xml", false)); 
     outputter.output(doc, writer); 
     writer.close(); 
     gc(); 
     System.out.println("After writing to XML file: " + (runtime.totalMemory() - runtime.freeMemory()) + " bytes"); 
    } 

    public static void main(String[] cmdArgs) throws IOException { 
     List<String> filenames = new ArrayList<String>(); 
     StringBuilder builder = new StringBuilder(); 
     // 30 unicode chracters, repated 500,000 times. The memory to store 
     // these file name strings should be about 30MB. 
     builder.append("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"); 
     for (int i = 0; i < 500000; i++) { 
      filenames.add(builder.toString()); 
     } 
     gc(); 
     System.out.println("After generating file names: " + (runtime.totalMemory() - runtime.freeMemory()) + " bytes"); 
     generateXml(filenames); 
     gc(); 
     System.out.println("Get back to main: " + (runtime.totalMemory() - runtime.freeMemory()) + " bytes"); 
    } 
} 

La sortie est:

After generating file names: 51941096 bytes 
After generating JDOM objects: 125766824 bytes 
After writing to XML file: 126036768 bytes 
Get back to main: 51087440 bytes 

Comme vous pouvez le voir, les objets JDOM utilisés sur les 70Mo.

Répondre

1

La raison pour laquelle JDOM a besoin de tant de mémoire est parce que JDOM est principalement une API basée sur l'arbre comme DOM (L'arbre de document est créé en mémoire, comme vous l'avez utilisé.). Mais c'est plus performant que DOM. Si vous créez des documents XML volumineux, vous voudrez peut-être envisager d'utiliser quelque chose comme XMLStreamWriter qui est livré avec JDK6

Voici une courte article sur ce que JDOM n'est pas capable de