我正在阅读一个大小为2.6GB的XML文件--JVM的大小为6GB。
但是我仍然在收到内存空间错误?
我在这里做错了什么......
作为参考,我输出JVM的最大内存和可用内存属性 -
最大内存显示为大约5.6GB,但可用内存仅显示为90MB ...为什么只有90MB显示为空闲,尤其是当我甚至没有开始任何处理时...我刚开始这个程序?
答案 0 :(得分:8)
通常,在将结构化文本转换为Java中的相应数据结构时,需要 lot 比输入文件的大小更多的空间。除了字符串所需的空间之外,使用的各种数据结构还有很多开销。
例如,每个String
实例都有大约32-40字节的额外开销 - 更不用说每个字符都存储在两个字节中,这有效地使空间需求增加了一倍ASCII编码的XML。
然后在结构中存储String时会产生额外的开销。例如,为了在String
中存储Map
实例,您将需要大约16-32字节的额外开销,具体取决于实现以及您如何衡量使用情况。
6GB很可能不足以同时存储解析的2.6GB XML文件......
底线:
如果要在内存中加载如此大的XML文件(例如使用DOM解析器),那么您可能做错了什么。基于流的解析器(如SAX)应该具有更为适度的要求。
或者考虑将XML文件转换为更有用的文件格式,例如嵌入式数据库 - 甚至是基于服务器的实际数据库。这将允许您处理更大的文档而不会出现问题。
答案 1 :(得分:1)
你应该避免一次将整个xml加载到内存中,而是使用一个可以处理大量xml的专用类。
答案 2 :(得分:1)
这里可能有几个不同的问题。
但对于初学者:
1)如果您使用的是64位操作系统,请确定您使用的是64位JVM
2)确保您的代码尽快关闭您打开的所有资源。
3)将对已完成的大对象的引用显式设置为“null”。
......和......
答案 3 :(得分:1)
您无法将2.6 GB XML图像作为仅6 GB的文档加载。正如jhordo建议的那样,该比率更可能是12比1.这是因为每个字节变成一个16位字符,每个标签,属性和值变成一个至少有32字节开销的字符串。
相反,您应该使用SAX或基于事件的解析器来逐步处理文件。这样,它只会保留您需要保留的数据。如果您可以一次性处理所有内容,则无需保留任何内容。