Что происходит, когда коллекция в Java увеличивается до предела?

У меня есть служба, которая обрабатывает все вызовы, сделанные к ней в памяти, потому что мы не хотим потерять данные, и в то же время нам нужно, чтобы эта служба когда-либо отказывала из-за какой-либо внешней зависимости (например, БД). Затем эти поэтапные вызовы обычно обрабатываются в фоновом режиме.

Если по какой-либо причине, если звонков слишком много и у нас не хватает памяти, нам нужно встревожиться.

Итак, вопрос, который проще сказать, заключается в следующем: какое исключение мне нужно отследить или отследить, чтобы уведомить меня, если добавление в список не удается из-за недостатка ресурсов? Приведет ли это к ООМ в самой ВМ, или также существует ограничение на уровне коллекции?

Если ограничения на уровне сбора нет, как бы вы порекомендовали мне отслеживать использование службы? В настоящее время у нас есть показатели использования кучи и памяти. Этого достаточно? Кроме того, JVM настроены на уничтожение при ошибке OOM (это потому, что диспетчер виртуальных машин затем перезапускает любой процесс, которым он управляет при уничтожении).

3 ответа

Решение

Исключение, которое будет брошено OutOfMemoryException, Это исключение может быть брошено в любую часть вашего приложения, когда ваша коллекция съест все доступное пространство кучи.

Однако, если вы знаете, что он может быть потенциально брошен для конкретной коллекции, лучшим способом может быть предотвращение этого, то есть ограничение этой коллекции или использование кэширования, чтобы неиспользуемые сущности выселялись и перезагружались по требованию. Для облегченной реализации кэша я бы порекомендовал CacheBuilder от Guava.

ОБНОВИТЬ

Поскольку все предлагают хранилище на основе FS, вот мое простое предложение:

  • CacheBuilder для загрузки ваших сериализованных данных из NoSQL DB
  • Сериализатор Kryo для преобразования ваших объектов в byte[]
  • MapDB для хранения (или любое другое встроенное решение NoSQL, которое вы предпочитаете).

Вот что я нашел в спецификации Collection.add:

Если коллекция отказывается добавлять конкретный элемент по любой причине, кроме той, что она уже содержит элемент, она должна выдать исключение (а не возвращать false). Это сохраняет инвариант, что коллекция всегда содержит указанный элемент после возврата этого вызова.

Это не указывает, какое исключение, поэтому разные коллекции могут выдавать разные исключения.

Я думаю, что неудачное завершение работы приложения не является идеальным выбором для дизайна. У вас должно быть пороговое значение для размера коллекции, и вы должны решить, что делать в этом случае: очистить ее где-нибудь (диск?), Отправить уведомление (JMX/email), выдать ошибку (или позволить распространению OOME).

Тем не менее, я собираюсь дать вам рекомендации по дизайну. Из вашего краткого и слегка загадочного описания службы мне кажется, что вам нужна рабочая очередь, чтобы находиться где-то за пределами вашей службы, например, JMS-сервер или даже база данных. Таким образом, ваш фоновый процесс сможет забрать запрос из очереди (дБ) и обработать его, даже если ваша служба по какой-либо причине умерла.

Другие вопросы по тегам