2015-10-17 3 views
0

У меня есть служба, которая вызывает базу данных и выполняет обратный вызов для каждого результата.Executor Service and Huge IO

ExecutorService service = Executors.newFixedThreadPool(10); 
service.exectute(runnable(segmentID, callback)); // database is segmented 

Runnable является:

call database - collect all the rows for the segment keep in memory 
perform callback(segment); 

Теперь вопрос я получаю огромные строки, возвращаемые базой данных и мое понимание исполнителем услуг будет планировать темы всякий раз, когда они простаивают в I/O. Поэтому я ухожу из памяти.

Есть ли способ ограничить только 10 потоков, выполняемых одновременно, и не выполняется планирование службы-исполнителя?

По какой-то причине я должен хранить все строки сегмента в памяти. Как я могу предотвратить запуск OOM, выполнив это. Является ли Executor сервисом newFixedThreadPool для этого?

Пожалуйста, дайте мне знать, если я пропустил что-либо.

Thanks

+1

Неизвестный код, делающий неизвестные вещи, вызывает проблемы с памятью. Трудно помочь. Отправьте свой код. Покажите нам, как вы называете базу данных. Покажите нам, что делают обратные вызовы. –

+0

Предположим, что я хочу выполнить огромную операцию ввода-вывода внутри runnable и сохранить значения, полученные в памяти. Если я скажу, что 10 потоков, выполняющих IO и другие, неактивны, я не перейду в OOM, но если служба-исполнитель планирует другие потоки, в то время как эти 10 выполняют IO, тогда я обязательно пойду в OOM. –

+0

Если вы отправляете 10 задач или более исполнителям, которые имеют доступные потоки hs 10, 10 потоков * будут * выполняться одновременно. В этом весь смысл. Если вы хотите, чтобы только два потока выполнялись параллельно, создайте исполнителя с двумя потоками. Но в любом случае, если все останется в памяти даже после выполнения задачи, количество потоков ничего не изменит. –

ответ

1

Вы должны использовать фиксированный пул потоков. Существует правило, что вы должны создавать только N потоков, где N должно быть в том же порядке, что и количество ядер в CPU. Там обсуждается размер N, и вы можете прочитать об этом больше here. Для обычного процессора мы могли бы говорить 4,8, 16 потоков.

Но даже если вы запускали свою программу в кластере, и я думаю, что вы этого не делаете, вы не можете просто извлечь 20k строк из БД и притворяться, чтобы порождать потоки 20k. Если вы это сделаете, производительность вашего приложения сильно ухудшится, потому что большинство циклов процессора будет потребляться при переключении контекста.

Теперь даже с фиксированным пулом потоков вы можете работать в исключениях OOM в любом случае, если данные извлекаются в памяти одновременно. Я думаю, что единственным решением для этого является выбор небольших фрагментов данных или запись данных в файл по мере его загрузки.

+0

Получает чувство благодарности :) –