Сообщение актера Akka нуждается в пуле памяти
Я новый в Java. Я программист на С ++ и в настоящее время изучаю Java в течение 2 месяцев. Извините за мой бассейн английский.
У меня есть вопрос, если ему нужен пул памяти или пул объектов для актерской модели Akka. Я думаю, что если я отправлю какое-то сообщение от одного актера одному из других актеров, мне придется выделить некоторую кучу памяти (точно так же, как новую Some String или новую Some BigInteger и т. Д.). И раз, сборщик мусора будет Я начал (я не уверен, что это будет запущено), и это заставляет мое приложение вычислять медленно.
Поэтому я ищу способ сделать пул памяти и не удалось (Java не поддерживает пул памяти). И я мог бы создать пул объектов, но в других проектах я не нашел никого, кто бы использовал объектный пул с актером (также на домашней странице Akka).
Есть ли какие-либо документы на эту тему в разделе Акка? Скажите, пожалуйста, ссылку или решение моего вопроса.
Благодарю.
2 ответа
Использование ArrayBlockingQueue для хранения пула ваших объектов должно помочь,
Вот пример кода.
Чтобы создать пул и вставить в него экземпляр объекта пула.
BlockingQueue<YOURCLASS> queue = new ArrayBlockingQueue<YOURCLASS>(256);//Adjust 256 to your desired count. ArrayBlockingQueues size cannot be adjusted once it is initialized.
queue.put(YOUROBJ); //This should be in your code that instanciates the pool
и позже, где вам это нужно (в вашем актере, который получает сообщение)
YOURCLASS instanceName = queue.take();
Возможно, вам придется написать некоторый код вокруг этого, чтобы создать и управлять пулом. Но это суть этого.
Если, скорее всего, вы используете Akka на нескольких компьютерах, сообщения сериализуются по проводам и отправляются другому экземпляру. Это означает, что простого локального пула памяти будет недостаточно.
Хотя технически возможно, что вы пишете собственную реализацию JSerializer (см. Документ здесь), которая хранит локальные сообщения в пуле памяти после их десериализации, я считаю, что это немного излишне для большинства приложений (и их легко объединить и даже ухудшить) производительность с поиском времени на карте)
Да, когда включится GC, приложение будет немного тормозить при больших нагрузках. Но в 95% сценариев, особенно в таких рабочих средах, как Akka, GC не будет вашим узким местом: IO будет.
Я не говорю, что ты не должен этого делать. Я говорю, что прежде чем приступить к выполнению задачи, учитывая ее нетривиальность, вы должны измерить влияние GC на ваше приложение во время выполнения с помощью таких вещей, как Kamon или другие специализированные решения для мониторинга Akka, и только после того, как вы уверены, что оно того стоит. это вы можете пойти на это.
Можно выполнить объединение объектов для минимизации длинного хвоста задержки (жертвой медианы в многопоточной среде). рассмотрите возможность использования соответствующих очередей, например, из JCTools, Distruptor или Agrona. Не забывайте о правилах взаимодействия для обмена состояниями через изменяемое состояние с использованием нескольких повторений в сохраненных объектах - https://youtu.be/nhYIEqt-jvY (лучший контент, который мне удалось найти).
Опять же, не ожидайте улучшения во всем, используя такие немного опасные методы. Вы потеряете эффективность кеш-памяти L1-L3 и сделаете PCI вежливым барьером.
Немного касательного (чтобы понять технологию с низкой задержкой): можно рассмотреть некоторую реализацию GC с более низкой задержкой, если вы хотите придерживаться Akka, или использовать настраиваемую реактивную модель, где пул объектов используется одним потоком или память копируется, например, Distrupptor. подход. Другой альтернативой является использование областей памяти (как работает Erlang VM). Он создает мусор, но в форме, удобной для обработки с помощью GC!
Если вы переходите к вводу-выводу с очень низкой задержкой и являетесь самым большим врагом задержки - забудьте о устаревшем TCP (против RDMA через Infininiband), переключателях (без переключения), доступе ОС к диску через вызовы ОС и файловой системе (используйте RDMA), забудьте о прерываниях, совместно используемых одно и то же ядро, а не закрепленные ядра (и без вращения для ввода) с реальным ядром ЦП (по сравнению с виртуальными / гиперпоточными) или обмен данными между NUMA или сообщениями одно за другим вместо аппаратной многоадресной рассылки (или лучшего оптического переключателя) для нескольких потребителей и не забывайте превращение Epsilon GC для JVM;)