获取堆空间内存错误 - 如何使用Java堆内存

时间:2012-12-28 16:52:39

标签: java memory-management memory-leaks heap-memory

我正在阅读一个大小为2.6GB的XML文件--JVM的大小为6GB。

但是我仍然在收到内存空间错误?

我在这里做错了什么......

作为参考,我输出JVM的最大内存和可用内存属性 -

最大内存显示为大约5.6GB,但可用内存仅显示为90MB ...为什么只有90MB显示为空闲,尤其是当我甚至没有开始任何处理时...我刚开始这个程序?

4 个答案:

答案 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”。

......和......

4)熟悉JConsoleVisualVM

答案 3 :(得分:1)

您无法将2.6 GB XML图像作为仅6 GB的文档加载。正如jhordo建议的那样,该比率更可能是12比1.这是因为每个字节变成一个16位字符,每个标签,属性和值变成一个至少有32字节开销的字符串。

相反,您应该使用SAX或基于事件的解析器来逐步处理文件。这样,它只会保留您需要保留的数据。如果您可以一次性处理所有内容,则无需保留任何内容。