Scala – 在本地范围内的大量文件上执行XML.loadFile时的高堆使
我试图从大量的xmls创建一个对象树.但是,当我在大约2000 xml文件(范围从100KB到200MB)上运行以下代码时(注意我已经注释掉了创建对象树的代码),我获得了8-9GB的大内存占用.我希望在下面的示例中内存占用量最小,因为代码不会保留任何引用,它只会创建Elem并将其抛弃.运行完整GC后,堆内存保持不变.
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() } 我的JVM选项是:-server -d64 -Xmx16G -Xss16M -XX:DoEscapeAnalysis -XX:UseCompressedOops 而jmap -histo的输出看起来像这样 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 解决方法
我无法重现这种行为.我使用以下程序:
import java.io._ import xml.XML object XMLLoadHeap { val filename = "test.xml" def addFile() { val is = new BufferedInputStream(new FileInputStream(filename)) val xml = XML.load(is) is.close() println(xml.label) } def createXMLFile() { val out = new FileWriter(filename) out.write("<foo>n") (1 to 100000) foreach (i => out.write(" <bar baz="boom"/>n")) out.write("</foo>n") out.close() } def main(args:Array[String]) { println("XMLLoadHeap") createXMLFile() (1 to args(0).toInt) foreach { i => println("processing " + i) addFile() } } } 我使用以下选项运行它:-Xmx128m -XX:HeapDumpOnOutOfMemoryError -verbose:gc,它基本上看起来可以无限期运行. 您可以尝试在仅使用最大的XML文件时查看是否执行此操作.问题可能不是处理许多文件,而是处理最大的文件.当在64位计算机上使用虚拟200MB XML文件进行测试时,我发现需要大约3G内存.如果是这种情况,您可能需要使用拉解析器.见XMLEventReader. 除此之外,假设您没有创建对象树,您可以使用-Xmx4G -XX:HeapDumpOnOutOfMemoryError,然后使用像MAT这样的工具分析堆转储.4GB应该足以解析最大的XML文件,到时候你得到内存不足错误,可能会分配足够的对象来确定哪个对象阻止了GC.很可能是一个持有各种解析的XML对象的对象. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |