#java #amazon-web-services #aws-lambda
#java #amazon-веб-сервисы #aws-lambda
Вопрос:
Мы получаем
java.lang.OutOfMemoryError: Metaspace
Поскольку мы не используем наше полное пространство памяти, мы полагаем, что это размер метапространства. Я видел несколько сообщений, в которых говорится, что мы можем установить «некоторые» настройки jvm, но я хочу установить некоторые из них:
java -XX:MaxMetaspaceSize=192mb (just example sizes)
- Возможно ли установить эти параметры?
- Где в yml я могу это сделать?
Обновить
Вот текущие настройки из лямбды (через: ManagementFactory.getRuntimeMXBean().getInputArguments())
-XX:MaxHeapSize=445645k, -XX:MaxMetaspaceSize=52429k, -XX:ReservedCodeCacheSize=26214k, -XX: UseSerialGC, -Xshare:on, -XX:SharedArchiveFile=/var/lang/lib/server/runtime.jsa, -XX:-TieredCompilation, -Djava.net.preferIPv4Stack=true
Комментарии:
1. Вам действительно нужна куча объемом 222 ГБ? Не с помощью Lambda. Это среда объемом не более 3 ГБ.
2. Нет, это был пример, который я нашел в Интернете. Извините. Исправлено.
3. См . раздел Изменение среды выполнения Lambda
4. возможно, у вас гораздо большая проблема, метапространство по умолчанию не ограничено.
5. Каковы ваши текущие настройки памяти? Что произойдет, если вы увеличите это значение? Вы получаете ту же ошибку при запуске за пределами Lambda? Есть ли у вас какие-либо идеи о том, что потребляет метапространство?
Ответ №1:
Вы подходите к этому с неправильного направления. Согласно документам Java8:
Объем встроенной памяти, который может использоваться для метаданных класса, по умолчанию не ограничен. Используйте параметр MaxMetaspaceSize, чтобы установить верхний предел объема встроенной памяти, используемой для метаданных класса
Итак, единственное, что явно настраивает размер метапространства, — это ограничить объем метапространственной памяти; это не увеличит его. Если вы хотите выделить больше памяти для метапространства, вам необходимо уменьшить заранее определенный размер остальной части кучи.
Однако это неправильно.
Реальная проблема в том, что вы делаете что-то, что загружает больше классов, чем может поместиться в доступном метапространстве. Наиболее вероятной причиной является то, что вы только что выбрали конфигурацию памяти, которая слишком мала для вашего пакета развертывания. Вы не сказали, каково ваше настроенное значение, но если бы мне пришлось догадаться, это около 512 МБ. Попробуйте 1024 или 1536.
Также возможно, что вы — или одна из библиотек, которые вы используете, — динамически создаете классы неограниченным образом. В этом случае не имеет значения, сколько памяти вы выделяете для своего Lambda, в конечном итоге вам не хватит места.
Способ диагностировать это — запустить ваш код за пределами Lambda, используя флаги TraceClassLoading
и TraceClassUnloading
. Вы ищете классы с «сгенерированными» именами, обычно случайными последовательностями цифр или букв.
Комментарии:
1. Правильно. Но смотрите Новое обновление выше. Мы не используем весь объем памяти, поэтому, если бы мы могли увеличить метапространство, мы были бы на вес золота. Мы только что добавили драйвер Snowflake, и он огромен.
2. @markthegrea — хотя я удивлен, что Amazon явно устанавливает эту опцию, это не меняет моего совета: если это вызвано количеством загружаемых вами классов, а не созданием неконтролируемого класса, тогда правильным решением будет увеличить вашу настроенную память.
3. Хотя вы могли бы реализовать собственную пользовательскую среду выполнения, которая предоставляет другое значение для этого параметра (или полностью исключает его), время на создание и поддержку этой пользовательской среды выполнения займет много гигабайт-секунд.
4. Я тоже удивлен. Да, мы увеличили размер jvm с 512 до 1024, и это устранило нашу проблему, но кажется немного странным, что нам приходится тратить деньги на это (это не так много). Lambda — это обычный сервер, и у них, вероятно, возникнут проблемы с людьми, которые будут возиться с настройками. Спасибо за помощь!
Ответ №2:
Существует способ настроить максимальное использование памяти. Примечание: существуют ограничения, минимальное значение — 128, а максимальное — 3008 МБ. Подробности смотрите здесь
Использование serverless.yml
provieder:aws
memorySize: 512 # Overwrite the default memory size. Default is 1024
Использование SAM template.yml
LambdaFunction:
Type: AWS::Serverless::Function
Properties:
MemorySize: 512
Если вы планируете иметь очень настраиваемую настройку, существует настраиваемая среда выполнения — https://docs.aws.amazon.com/lambda/latest/dg/runtimes-custom.html
Вам нужен загрузочный файл, который является точкой входа и где вы могли бы определить, как запускается приложение.