Я создал тестовый файл .txt, содержащий только символ «а». Размер файла составляет около 20 МБ. Я пытался прочитать файл тремя способами
Использование BufferedReader
String fileName = "C:\\testFile.txt";
FileReader fileReader = new FileReader(fileName);
try (BufferedReader bufferedReader = new BufferedReader(fileReader)) {
String line;
while ((line = bufferedReader.readLine()) != null) {
System.out.println(line);
}
}
Использование сканера
Scanner sc = null;
try {
sc = new Scanner(new File("C:\\testFile2.txt"), "UTF-8");
while (sc.hasNextLine()) {
String line = sc.nextLine();
System.out.println(line);
}
if (sc.ioException() != null) {
throw sc.ioException();
}
} finally {
if (sc != null) {
sc.close();
}
}
И, используя поток Java8
try (Stream<String> stream = Files.lines(Paths.get(fileName))) {
stream.forEach(System.out::println);
}
Я установил размер кучи jvm, используя конфигурацию запуска eclipse, как показано здесь http://www.planetofbits.com/eclipse/increase-jvm-heap-size-in-eclipse/
Во всех трех случаях мое значение: -Xms5M -Xmx100M.
Несмотря на то, что размер файла составляет 20 МБ, он всегда выдает java.lang.OutOfMemoryError. Когда я устанавливаю размер кучи на -Xmx200M, все работает нормально. Интересно, что съедает память и есть ли другой более эффективный способ чтения файла.
Любая помощь приветствуется.
ИЗМЕНИТЬ Профилирование
Спасибо Ранн и Адам. Я использовал Jprofiler для кода сканера. Использование памяти показано в массив char[] занимает много и Общее использование памяти
Интересно видеть, что массив char[] занимает так много. Не знаю, почему!
Боковое примечание: теперь я изменил свой тестовый файл, чтобы он содержал целое число и новую строку, поэтому каждая строка содержит случайное целое число. Имея это на месте, я могу легко прочитать файл (даже размером 100 МБ) с помощью сканера, так как он будет читать только одну строку за раз. Раньше в файле был только символ «а» и не было новой строки.
int
s. - person Code-Apprentice   schedule 23.06.2018