Sto provando a creare un albero di oggetti da un numero elevato di xmls. Tuttavia, quando eseguo il seguente codice su circa 2000 file xml (da 100 KB a 200 MB) (si noti che ho commentato il codice che crea l'albero degli oggetti), ottengo un ingombro di memoria di 8-9 GB. Mi aspetto che l'impronta della memoria sia minima nell'esempio seguente, poiché il codice non mantiene alcun riferimento, ma crea Elem e lo getta via. La memoria heap rimane la stessa dopo aver eseguito il GC completo.Scala: utilizzo elevato dell'heap quando eseguito XML.loadFile su un numero elevato di file nell'ambito locale
def addDir(dir: File) {
dir.listFiles.filter(file => file.getName.endsWith("xml.gz")).foreach { gzipFile =>
addGzipFile(gzipFile)
}
}
def addGzipFile(gzipFile: File) {
val is = new BufferedInputStream(new GZIPInputStream(new FileInputStream(gzipFile)))
val xml = XML.load(is)
// parse xml and create object tree
is.close()
}
mie opzioni JVM sono: -server -d64 -Xmx16G -Xss16M -XX: + DoEscapeAnalysis -XX: + UseCompressedOops
e l'uscita del jmap -histo sembra questo
num #instances #bytes class name ---------------------------------------------- 1: 67501390 1620033360 scala.collection.immutable.$colon$colon 2: 37249187 1254400536 [C 3: 37287806 1193209792 java.lang.String 4: 37200976 595215616 scala.xml.Text 5: 18600485 595215520 scala.xml.Elem 6: 3420921 82102104 scala.Tuple2 7: 213938 58213240 [I 8: 1140334 36490688 scala.collection.mutable.ListBuffer 9: 2280468 36487488 scala.runtime.ObjectRef 10: 1140213 36486816 scala.collection.Iterator$$anon$24 11: 1140210 36486720 scala.xml.parsing.FactoryAdapter$$anonfun$startElement$1 12: 1140210 27365040 scala.collection.immutable.Range$$anon$2 ... Total 213412869 5693850736
Ha eseguito il programma (dalla console di scala, in modo che il vm rimanga attivo) per il singolo file xml più grande (438 MB). L'utilizzo dell'heap non sembra essere il problema –
Ha eseguito il programma (dalla console di scala, in modo che il vm rimanga attivo) per il singolo file xml più grande (438 MB). Preso il sommario dell'heap dopo aver caricato il file ed eseguito gc completo. L'utilizzo dell'heap non sembra essere il problema poiché vengono utilizzati solo 111 MB di vecchia generazione (e 0 di nuova generazione). Tuttavia, l'output del comando 'top' mostra la dimensione residua (RES) di 4,8 GB. –
D'altra parte, l'esecuzione con heap a 32 bit (3 GB) genera: java.lang.OutOfMemoryError: limite di overhead GC superato su scala.xml.parsing.FactoryAdapter.startElement (FactoryAdapter.scala: 136) su com.sun.org .apache.xerces.internal.parsers.AbstractSAXParser.startElement (AbstractSAXParser.java:501) in com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl.scanStartElement (XMLDocumentFragmentScannerImpl.java:1363) in com.sun .org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl $ FragmentContentDriver.next ... –