Страницы

Поиск по вопросам

вторник, 15 января 2019 г.

Память JVM: как оптимизировать многопоточное приложение?

Господа, насколько я понимаю модель памяти JVM выглядит так: если поток вызывает некий метод класса, то все локальные переменные которые там используются будут созданы не в HeapMemory, а в StackMemory. Этот StackMemory тоже очищается GC и тоже входит как слагаемое в полную доступную JVM память (ее можно получить как Runtime.maxMemory()), и, следовательно, чем больше потоков - тем больше занято памяти, даже при том что HeapMemory остается без изменений. Т.о. можно записать: Runtime.freeMemory() = Runtime.maxMemory() - Thread1Stack - Thread2Stack - ... - HeapSpace. Поправьте меня, пожалуйста, если я не прав. К чему я это спрашиваю: в моем приложении есть специальный поток-наблюдатель, который все время логгирует значение Runtime.freeMemory() и иногда оно опускается до сотен байт (однажды вообще было Runtime.freeMemory() = 8 ). Это приводит к тому, что процесс замедляется и Томкат не отвечает на HTTP запросы. Возникает вопрос: может ли при таком низком значении памяти запускаться GC? Я предполагаю, что должна быть связь оптимального количества потоков не только с количеством процессоров, но и с размером памяти. Как мне определить эту связь? У меня Томкату доступно Runtime.maxMemory() = 64МБ, при этом обычно мое приложение запускает 3-4 потока, максимум до 10-12. Мне казалось, что такая нагрузка подходит для процессора т.к. все эти мои потоки очень много спят. Однако судя по тому как мало памяти остается - думать надо не только о процессоре, но и о памяти. Итак, как понять какое количество потоков оптимально для многопоточного приложения? Какие кроме Runtime.freeMemory() методы отслеживания состояния памяти вы используете? (я не могу запустить профайлер на удаленном хостинге).


Ответ

Вы не правы. Объекты всегда создаются в куче. В стеке живут примитивные типы (byte, char, short, int, long, boolean). В стеке хранятся ссылки на объекты в куче. Все ваши последующие рассуждения, как следствие, не верны. Если у вас всё встревает или даже падает по OOM, то у вас утечка. В общем, количетсво потоков и память связаны только когда потоков очень много (тысячи). Кроме того, каждому потоку можно указать конкретный размер стека, если вы знаете, какова максимальная требуемая глубина и нет рекурсии. Так что количетсво потоков выбирается таким образом, чтобы оно по возможности не было пропорционально количеству данных приложения и количеству пользователей. Что же до трёх потоков, то вы забываете о самом томкате, который запускает... очень немало потоков (в зависимости от конфигурации).

Комментариев нет:

Отправить комментарий