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