Определенно ловить ошибку - худший подход. Ошибка происходит, когда НИЧЕГО вы не можете с этим поделать. Даже не создавать журнал, пух, как "... Хьюстон, мы потеряли ВМ".
Я не совсем понял вторую причину. Это было плохо, потому что трудно связать SOME_MEMORY с операциями? Не могли бы вы перефразировать это для меня?
Единственная альтернатива, которую я вижу, - это использовать жесткий диск в качестве памяти (RAM / ROM, как в прежние времена). Я думаю, это то, на что вы указываете в своем «еще более медленном, менее требовательном подходе»
У каждой платформы есть свои ограничения, поддержка java столько, сколько ОЗУ готово предоставить вашему оборудованию (ну, на самом деле, вы настраиваете виртуальную машину) В Sun JVM подразумевается, что это можно сделать с помощью
-Xmx
Опция
как
java -Xmx8g some.name.YourMemConsumingApp
Например,
Конечно, вы можете попытаться выполнить операцию, которая занимает 10 ГБ ОЗУ
Если это ваш случай, вам непременно следует перейти на диск.
Кроме того, использование шаблона стратегии может сделать более приятный код. Хотя здесь это выглядит излишне:
if( isEnoughMemory( SOME_MEMORY ) ){
strategy = new InMemoryStrategy();
}else{
strategy = new DiskStrategy();
}
strategy.performTheAction();
Но это может помочь, если "else" содержит много кода и выглядит плохо. Кроме того, если каким-то образом вы можете использовать третий подход (например, использовать облако для обработки), вы можете добавить третью стратегию
...
strategy = new ImaginaryCloudComputingStrategy();
...
: P
РЕДАКТИРОВАТЬ
После получения проблемы со вторым подходом: если есть случаи, когда вы не знаете, сколько ОЗУ будет использовано, но знаете, сколько у вас осталось, вы можете использовать смешанный подход (ОЗУ, когда у вас достаточно, ROM [диск], когда нет)
Предположим, это теоретическая проблема.
Предположим, вы получили файл из потока и не знаете, насколько он большой.
Затем вы выполняете некоторую операцию с этим потоком (например, зашифруете его).
Если вы используете только оперативную память, это будет очень быстро, но если файл достаточно большой, чтобы использовать всю память вашего приложения, вам придется выполнить некоторые операции в памяти, а затем перейти к файлу и сохранить там временные данные. ,
Виртуальная машина будет работать при исчерпании памяти, вы получите больше памяти, а затем выполните другой блок. И это повторяется до тех пор, пока не будет обработан большой поток.
while( !isDone() ) {
if( isMemoryLow() ){ //Runtime.getRuntime().freeMemory() < SOME_MEMORY + some other validations
swapToDisk(); // and make sure resources are GC'able
}
byte [] array new byte[PREDEFINED_BUFFER_SIZE];
process( array );
process( array );
}
cleanUp();