Я полностью согласен и с Тоби, и с Джоном Васильевым. S3 отлично подходит для выгрузки больших медиа-объектов, если вы можете терпеть связанные с этим проблемы. (Экземпляр собственного приложения делает это для FLV 10-1000 МБ и MP4.) Например, нет частичных запросов (заголовок диапазона байтов). Нужно справиться с этим «вручную», время простоя и т. Д.
Если это не вариант, код Джона выглядит хорошо. Я обнаружил, что байтовый буфер 2k FILEBUFFERSIZE является наиболее эффективным в микробенчмарках. Другим вариантом может быть общий FileChannel. (FileChannels потокобезопасны.)
Тем не менее, я бы добавил, что предположение о том, что вызвало ошибку нехватки памяти, является классической ошибкой оптимизации. Вы повысите свои шансы на успех, работая с жесткими метриками.
- Поместите -XX: + HeapDumpOnOutOfMemoryError в параметры запуска JVM, на всякий случай
- использовать jmap на работающей JVM ( jmap -histo ) под нагрузкой
- Анализировать метрики (jmap -histo out put или jhat посмотреть на ваш дамп кучи). Вполне возможно, что ваша нехватка памяти приходит откуда-то неожиданно.
Конечно, есть и другие инструменты, но jmap и jhat поставляются с Java 5+ «из коробки»
Я подумал о том, чтобы записать файл на локальный временный диск и затем создать другой поток для обработки потоковой передачи, чтобы можно было повторно использовать поток сервлета tomcat. Кажется, это было бы очень тяжело.
Ах, я не думаю, что вы не можете этого сделать. И даже если бы вы могли, это звучит сомнительно. Поток Tomcat, который управляет соединением, нуждается в контроле. Если вы испытываете истощение потоков, увеличьте число доступных потоков в ./conf/server.xml. Опять же, метрики - это способ обнаружить это - не просто догадываться.
Вопрос: Вы также работаете на EC2? Каковы параметры запуска JVM вашего кота?