2009-08-07 2 views
2

Какая очередь блокировки Java лучше всего подходит для нескольких сценариев производителя и одного или нескольких потребителей?Какая очередь блокировки Java лучше всего подходит для нескольких сценариев производителя и одного или нескольких потребителей?

Я тестирую с LinkedBlockingQueue, но получаю исключение OutOfMemoryError.

Я пытаюсь добиться следующих целей.

  1. производитель создает объект & ставит в очередь.
  2. потребитель захватывает данные из очереди & вставляется в базу данных. Было бы 400 производителей, и я могу настроить потребителей по своему желанию.

Дай мне знать какие-либо идеи.

Update

Производитель: Он должен слушать сокет-сервер. Он считывает данные из сокета &, создавая объект (объекты домена) и помещая его в очередь.

Потребитель: Возьмите объект из очереди & вставки в БД (Hiberante & пула соединений поддерживается)

Это мое реальное окружение. Процесс должен иметь возможность обрабатывать не менее 200 записей/сек. Я тестирую масштабируемость процесса и способы его улучшения. Надеюсь, это даст лучшую идею.

Полезные ссылки:

vmoptions

Monitoring and Managing Java SE 6 Platform Applications

BlockingQueue

ответ

5

Проблема не в которой Queue реализации вы используете, а как подойти к проблеме дросселирования ваших производителей если вашим потребителям не угнаться. Одним из возможных решений является создание LinkedBlockingQueue с фиксированной емкостью, и ваши продюсеры звонят offer(E e), который вернет false, если очередь заполнена.

Другим возможным решением является адаптация количества производителей и потребителей.

+2

+1 Я согласен, кажется, что ваша очередь не имеет разумной емкости - по умолчанию Integer.MAX_VALUE, который довольно большой. Если вы настроили емкость на что-то разумное и все еще имеете проблемы, то проверьте настройки Java-heapsize -Xmx и т. Д. – pjp

+0

Спасибо, ребята, я не могу уменьшить размер производителей в реальном времени, поэтому мне нужно его обработать. Если я использую предложение, я теряю этот объект, не так ли? Я использую put() и take(). который будет ждать в зависимости от состояния очереди. Я сконфигурировал -vmargs как -Xms512m -Xmx1024m в конфигурации запуска eclipse. – nayakam

2

Является ли каждый производитель отдельный поток? Не забывайте, что каждый поток будет выделять (по умолчанию) 512 тыс. Памяти для своего стека (в вашем случае требуется 200 МБ памяти VM только для потоков). Вы можете уменьшить это с помощью -Xss.

В качестве альтернативы, насколько велики объекты, которые вы ставите в очередь? Я не думаю, что у вас есть queue проблема, так как какая-то проблема масштабирования - например. производители, производящие быстрее, чем потребители, могут потреблять.

+0

Спасибо за ваш вклад. Я проверил рост размера очереди, увеличившись между 80 к 90 к и начал выбросить ошибку OutOfMemoryError. Queue сохраняет класс java, который является классом домена для таблицы, содержит 10 полей. – nayakam

+0

Если ваш объект домена (скажем) 500 байтов, то ваша очередь будет потреблять .5kb * 90e3 = 45Mb. На самом деле это не так. Поэтому я бы снова посмотрел на вашу память VM и, возможно, a) увеличил размер виртуальной машины, b) уменьшил размер стека потоков. Вышеописанная догадка, кстати, не зная, насколько велик ваш объект домена, или сколько еще делает ваше приложение. –

+0

Спасибо за ваш интерес. Я увеличил размер виртуальной машины до -vmargs как -Xms512m -Xmx1024m. и я настроил время ожидания 1000 мс для производителей (400) и 100 мс для потребителей (10). Теперь процесс может обрабатывать 400 записей/сек. – nayakam

1

Кажется, что LinkedBlockingQueue - лучший выбор для вашей проблемы. Я предлагаю вам запустить вашу программу с помощью переключателя -XX: + HeapDumpOnOutOfMemoryError и проанализировать файл дампа, чтобы узнать, что вызвало проблему. Тогда вы сможете решить это намного проще.

+0

Спасибо, я не смог получить файл сброса, который я установил -XX: + HeapDumpOnOutOfMemoryError для программирования аргумента, ссылка REF [http://java.sun.com/javase/6/ webnotes/trouble/TSG-VM/html/clopts.html] – nayakam

+0

Попробуйте найти диск для файлов * .hprof –

+0

Да, я не правильно передал параметр JVM. Теперь я получил файл, но когда я пытаюсь выполнить echo с помощью jhat-утилиты, он бросает исключение. – nayakam

Смежные вопросы