Зачем беспокоиться о расчете, сколько предметов вы можете держать? Как насчет того, чтобы позволить java сообщать вам, когда вы израсходовали всю свою память, перехватить исключение и продолжить. Например,
// prepare output medium now so we don't need to worry about having enough
// memory once the treeset has been filled.
BufferedWriter writer = new BufferedWriter(new FileWriter("output"));
Set<?> set = new TreeSet<?>();
int linesRead = 0;
{
BufferedReader reader = new BufferedReader(new FileReader("input"));
try {
String line = reader.readLine();
while (reader != null) {
set.add(parseTuple(line));
linesRead += 1;
line = reader.readLine();
}
// end of file reached
linesRead = -1;
} catch (OutOfMemoryError e) {
// while loop broken
} finally {
reader.close();
}
// since reader and line were declared in a block their resources will
// now be released
}
// output treeset to file
for (Object o: set) {
writer.write(o.toString());
}
writer.close();
// use linesRead to find position in file for next pass
// or continue on to next file, depending on value of linesRead
Если у вас все еще проблемы с памятью, просто увеличьте размер буфера считывателя, чтобы зарезервировать больше памяти.
Размер по умолчанию для буфера в BufferedReader составляет 4096 байт. Таким образом, когда вы закончите чтение, вы освободите до 4 Кб памяти. После этого ваши дополнительные потребности в памяти будут минимальными. Вам нужно достаточно памяти для создания итератора для набора, давайте будем щедрыми и предположим, 200 байтов. Вам также понадобится память для хранения строкового вывода ваших кортежей (но только временно). Вы говорите, что кортежи содержат около 200 символов. Давайте удвоим это, чтобы учесть разделители - 400 символов, что составляет 800 байт. Так что все, что вам действительно нужно, это дополнительные 1 Кбайт. Так что вы в порядке, так как вы только что выпустили 4k байтов.
Причина, по которой вам не нужно беспокоиться о памяти, используемой для хранения строкового вывода ваших кортежей, заключается в том, что они недолговечны и упоминаются только в выходных данных цикла. Обратите внимание, что Writer скопирует содержимое в свой буфер и затем отбросит строку. Таким образом, при следующем запуске сборщика мусора память может быть восстановлена.
Я проверил, и OOME в add
не оставит TreeSet в несогласованном состоянии, и выделение памяти для нового Entry
(внутренняя реализация для хранения пары ключ / значение) произойдет до того, как внутреннее представление изменено.