我正在使用jsoup解析器来读取HTML文件并使用提取的数据创建XML文件。我将在一个目录中运行这个代码/脚本,该目录有几个html文件(~250k - 300k文件),有些文件很大。
我遇到了
java.lang.OutOfMemoryError: Requested array size exceeds VM limit" or Java heap space
错误。我尝试使用不同的-Xmx
和-Xms
值运行VM,但我仍然遇到同样的错误。我附上了我的代码段。
我假设读取大文件时发生错误。有关如何解决此问题的任何想法?
String target_dir_output = "/test/";
File dir = new File(target_dir);
File[] files = dir.listFiles();
for (File f : files) {
if(f.isFile()) {
String fileName = f.getName();
String testValue = null;
try {
Document doc = Jsoup.parse(f, "UTF-8", "");
Elements metalinks = doc.select("meta[name=testValue]");
testValue = metalinks.first().attr("content");
String output = "<data>" + "\n";
output += "<testValue>" + testValue + "</testValue>" ;
output += "</data>";
FileOutputStream out = new FileOutputStream(fileName + ".xml");
out.write(output.getBytes());
out.close();
} catch (IOException e) {
e.printStackTrace();
}
答案 0 :(得分:4)
Java对程序可以分配的最大数组大小有限制。确切的限制是特定于平台的,但通常介于1到21亿个元素之间。
因此,当您面对java.lang.OutOfMemoryError:请求的数组大小超过VM限制时,手头的应用程序正在尝试分配比Java虚拟机可支持的更大的数组。
JVM中的本机代码引发错误。它在为数组分配内存之前发生,当JVM执行特定于平台的检查时:分配的数据结构是否可在此平台中寻址。
此错误不如您最初想象的那么常见。原因是基于Java数组由int索引的事实。如果你还记得,java中的最大正int是2 ^ 31 - 1 = 2,147,483,647。特定于平台的限制可以非常接近这个数字 - 例如在Java 1.7上的64位MB Pro上,我可以愉快地初始化最多2,147,483,645或Integer.MAX_VALUE-2元素的数组。
将数组的长度增加1,增加到Integer.MAX_VALUE-1会导致抛出熟悉的OutOfMemoryError。
但限制可能不是那么高 - 在使用OpenJDK 6的32位Linux上,在分配一个包含大约11亿个元素的数组时,你会遇到“java.lang.OutOfMemoryError:请求的数组大小超过VM限制”。要了解特定环境的限制,请运行一个小测试找出它。