Вы можете использовать результат Runtime.freeMemory()
, чтобы оценить объем доступной памяти. Однако может случиться так, что на самом деле много памяти занято недостижимыми объектами, которые скоро будут возвращены GC. Таким образом, вы можете использовать больше памяти, чем это. Вы можете попытаться вызвать GC раньше, но это не гарантирует ничего.
Вторая сложность заключается в оценке объема памяти, необходимого для числа, заданного пользователем. Хотя с таким количеством записей легко вычислить размер ArrayList, это может быть не все. Например, какие объекты хранятся в этом списке? Я ожидаю, что в каждой записи есть хотя бы один объект, поэтому вам нужно добавить и эту память. Вычислить размер произвольного Java-объекта гораздо сложнее (и на практике это возможно только в том случае, если вы знаете структуры данных и алгоритмы, лежащие в основе этих объектов). И затем во время выполнения алгоритма может быть создано много временных объектов (например, примитивы в штучной упаковке, итераторы, StringBuilders и т. Д.).
В-третьих, даже если доступной памяти теоретически достаточно для выполнения данной задачи, ее может быть практически недостаточно. Java-программы могут работать очень медленно, если куча неоднократно заполняется объектами, затем некоторые из них освобождаются, некоторые новые создаются и т. Д. Из-за большого количества сборщиков мусора.
Итак, на практике то, чего вы хотите достичь, очень сложно и, вероятно, почти невозможно. Я предлагаю просто попробовать запустить алгоритм и перехватить OutOfMemoryError.
Обычно отлов ошибок - это то, что вы не должны делать, но это похоже на случай, когда все в порядке (я делаю это в некоторых подобных случаях). Вы должны убедиться, что, как только выдается OutOfMemoryError, некоторая память станет доступной для GC. Обычно это не проблема, так как алгоритм прерывается, стек вызовов разматывается, и некоторые (возможно, многие) объекты больше недоступны. В вашем случае вы, вероятно, должны убедиться, что большой список является частью этих объектов, которые сразу становятся недоступными в случае OOM. Тогда у вас будет хороший шанс продолжить приложение после ошибки.
Однако учтите, что это не гарантия. Например, если у вас несколько потоков, работающих и занимающих память параллельно, другие потоки могут также получить ошибку OutOfMemoryError и не справиться с этим. Также алгоритм должен поддерживать тот факт, что он может быть прерван в любой произвольной точке. Поэтому следует убедиться, что все необходимые действия по очистке выполняются (и, конечно, у вас проблемы, если им требуется много памяти!).