Меню

Произошла ошибка при использовании metaspace майнкрафт

Обновлено: 30.01.2023

В Java, начиная с 8 версии, появилась новая вариация OutOfMemory error : Metaspace.

Происходит это в связи с переполнением этой самой области памяти, которая является по сути эквивалентом Permanent Generation, однако может динамически расширяться.

Вопрос опытным товарищам:
Возникали ли у вас подобные ситуации в вашей практике, за исключением случаев, когда использовались сторонние библиотеки?

Вот тут еще в 2013 году описывали работу Metaspace с примером переполнения без использования сторонних библиотек. Попробуйте, может взлетит.

Распространённые причины
нехватка памяти, нужно не менее 400 мб
неустойчивое соединение с инетом
антивирус блокирует подключения джава в целом
ошибка проверки сертификата при работе с ssl, возможные решения
настройте правильно время на компьютере
джава установлена неправильно переустановите ее
антивирус блокирует проверку сертификата, отключите или по возможности настройте его правильно.
————
чё делать то. время у меня стоит правильное джаву переустановил, антивирус отрубил, всё равно не хочет загружать версию. я хочу загрузить версию майна фордж 1 17 1. но каждый раз мне выдаёт такую ошибку. я перезагружал комп и тлаунчер сам. ни чё не помогает. хотя другие версии форджа загружаются. но мне нужно 1 17 1 помогите что делать.

Zenker Искусственный Интеллект (103540) Это уже зависит от OVH и разрабов тдаунчера

Проверял ещё в момент падения серверов, проверил и сейчас. Работал, работает, и, дай Бог, будет работать.

Артур Бабенко

В этой статье, мы бы хотели поделиться с вами объяснением большинства ошибок, которые может выдавать Minecraft во время запуска и подключения к серверам. Также мы приводим возможные варианты решения.

Ошибки связанные с вылетом Minecraft:

Bad Video Card Drivers – означает, что для вашей видеокарты не установлены, либо установлены слишком старые драйвера. Перейдите на сайт производителя и установите свежие драйвера.

Out of Memory – обычно Minecraft вылетает с этой ошибкой при нехватке оперативной памяти. Причиной может быть маленькое количество оперативной памяти, а также большое количество запущенных программ. Закройте все лишние программы. Если с памятью все ок, то ошибка возникает из за того что Java машине выделено мало памяти. Could not create the Java Virtual Machine — невозможно создать среду исполнения Java. Попробуйте обновить/переустановить Java.

Черный экран при запуске — вероятно, вы модифицировали minecraft.jar (установили мод, например), после чего он не прошел проверку на подлинность. Лечится обычно удалением папки META-INF из minecraft.jar

Ошибки связанные с серверами:

Bad Login, User not Premium – означает, что для входа на данный сервер требуется лицензия Minecraft. Если это ваш сервер, то отредактируйте файл server.properties, измените в нем значение online-mode=true на online-mode=false

The server responded with an invalid server key — проблема появилась в последних версиях Minecraft. Ошибку допустили разработчики игры. Решение проблемы мы описали в этой статье.

Connection reset — означает, что сервер обрубил ваше соединение. Обычно связано с недоступностью сервера, либо с проблемами в соединении.

Connection refused — сервер отклонил соединение. Означает, что по данному адресу нет запущенного сервера, либо имеются проблемы в соединении.

Read time out — вышло время ожидания ответа. Сервер и ваш клиент Minecraft общаются при помощи пакетов. Когда сервер либо клиент перестают отвечать на запросы (например у вас игра подвисла), выжидается какое то время (таймаут), после чего соединение обрубается. Сделано это для того, чтобы незаконченные висящие соединения закрывались и не создавали нагрузку.

Logged in from another location — кто-то зашел на сервер под вашим ником.

Internal Server Error — внутренняя ошибка сервера. Означает, что на сервере произошла какая-либо ошибка в выполняемом коде. Чаще появляется на самописных или модифицированных серверах.

Артем Буровцев

Артем Буровцев

Руслан Фомичев

Руслан Фомичев

Артём, через много лет я понял что это из-за мира, созданного на каком-то снапшоте. Удалил мир, и ошибки уже не было

Читайте также:

      

  • X rebirth скрипты как включить
  •   

  • Как поменять язык на псп
  •   

  • Как установить шкурки для world of tanks blitz на пк
  •   

  • Вылетает при выходе из бара cyberpunk 2077
  •   

  • Малиновка гта системные требования

The java.lang.OutOfMemoryError: Metaspace indicates that the amount of native memory allocated for Java class metadata is exausted. Let’s how this issue can be solved in standalone applications and cloud applications.

In general terms, the more classes you are loading into the JVM, the more memory will be consumed by the metaspace. In Java 8 and later, the maximum amount of memory allocated for Java classes (MaxMetaspaceSize) is by default unlimited, so in most cases there is no need to change this setting.

On the other hand, if you want to limit the amount of memory allocated for Java classes, you can set it as follows:

java -XX:MaxMetaspaceSize=3200m  

The current Metaspace size (i.e. committed) will be, generally, smaller than that. Why ? Because there is a setting, MaxMetaspaceFreeRatio, which prevents the Metaspace from growing too much.

MaxMetaspaceFreeRatio is a JVM option that sets the percentage of free space that the JVM should attempt to maintain in the metaspace. When the percentage of free space in the metaspace drops below this threshold, the JVM will attempt to free up space by unloading classes that are no longer in use. The default value of MaxMetaspaceFreeRatio is 70.

In conclusion, setting a high value for MaxMetaspaceSize, increase the chances of OutOfMemoryError: Metaspace

What is the solution ?

By increasing the upper limit of the attribute MaxMetaspaceSize might solve the issue in some cases. For example, if you can see the error upon application start up.

On the other hand, if you see this error at runtime, we recommend to investigate on the Root cause of the problem before increasing blindly the MaxMetaspaceSize.

In order to find the Root cause, we recommend that you follow these steps:

  1. Understand how the JVM manages the MetaSpace data
  2. Learn how to monitor the MetaSpace in a running Java application
  3. Check the Heap dump of your application to find offending Classes

How Java Hotspot manages MetaSpace Data

The Java Hotspot manages Metadata space as follows: firstly, the JVM requests an amount of space to the OS. Then, this space is  divided into chunks. A class loader allocates space for Metadata from its chunks.

java outofmemory metaspace

Class Metadata is deallocated when the corresponding Java class is unloaded and its chunks are recycled for reuse or returned to the OS. Java classes are unloaded as a result of Garbage collection, and garbage collections may be triggered in order to unload classes and deallocate class Metadata. When the space committed for class Metadata reaches a certain threshold (a high-water mark), a Garbage Collection happens.
After the Garbage Collection, the high-water mark may change depending on the amount of space freed from class Metadata.

Monitoring the MetaSpace with jstat

The simplest way to monitor the MetaSpace size is by means of the jstat tool which is available in the JDK. When used with the option -gcmetacapacity it provides the following information:

jstat -gcmetacapacity (PID)  

For example:

MCMN   MCMX      MC       CCSMN CCSMX       CCSC    YGC   FGC    FGCT    CGC    CGCT       
0.0   374784.0  140360.0  0.0   253952.0    21168.0  23     0    0.000     6    0.046   

And here is a description of the Labels:

  • MCMN: Minimum metaspace capacity (kB).
  • MCMX: Maximum metaspace capacity (kB).
  • MC: Metaspace capacity (kB).
  • CCSMN: Compressed class space minimum capacity (kB).
  • CCSMX: Compressed class space maximum capacity (kB).
  • YGC: Number of young generation GC events.
  • FGC: Number of full GC events.
  • FGCT: Full garbage collection time.
  • GCT: Total garbage collection time.

Besides the Metaspace capacity, pay attention to the Compressed class space maximum capacity. The CompressedClassSpaceSize is the amount of virtual memory reserved for compressing Class MetaData. Therefore, MaxMetaspaceSize should be larger than CompressedClassSpaceSize.

If MaxMetaspaceSize is set smaller than CompressedClassSpaceSize, the JVM auto adjusts CompressedClassSpaceSize using this formula:

CompressedClassSpaceSize = MaxMetaspaceSize - 2 * InitialBootClassLoaderMetaspaceSize

Other interesting options include the parameter -gcutil:

 $ jstat -gcutil (PID) | awk '{print($5)}' 

This will print the Metaspace utilization as a percentage of the space’s current capacity.

Monitoring the MetaSpace with Java Native Memory tracking

Another option to monitor the MetaSpace usage is the JVM parameter NativeMemoryTracking, which you can add to the start up parameters. For example:

-XX:+UnlockDiagnosticVMOptions -XX:NativeMemoryTracking=detail -XX:+PrintNMTStatistics

When you enable the Native Memory Tracking, you can request a report on the JVM memory usage using the following command:

$ jcmd <pid> VM.native_memory

If you check at the jcmd output, you will find at the bottom, the amount of native memory committed in the Internal (committed) section

Total: reserved=1334532KB, committed=369276KB
-                 Java Heap (reserved=524288KB, committed=132096KB)
                            (mmap: reserved=524288KB, committed=132096KB)
 
-                     Class (reserved=351761KB, committed=112629KB)
                            (classes #19111)
                            (  instance classes #17977, array classes #1134)
                            (malloc=3601KB #66765)
                            (mmap: reserved=348160KB, committed=109028KB)
                            (  Metadata:   )
                            (    reserved=94208KB, committed=92824KB)
                            (    used=85533KB)
                            (    free=7291KB)
                            (    waste=0KB =0.00%)
                            (  Class space:)
                            (    reserved=253952KB, committed=16204KB)
                            (    used=12643KB)
                            (    free=3561KB)
                            (    waste=0KB =0.00%)

In the line beginning with Metaspace, look for the used value. This is the amount of space the JVM uses for loaded classes. The committed value is the amount of space available for chunks. The reserved value is the amount of space reserved (but not necessarily committed) for metadata.

Querying the Meta Space from an Heap Dump

To have more insights on the MetaSpace error, you should inspect the Heap of your Java application. You can use the jmap command line to trigger a Heap Dump:

jmap -dump:format=b,file=dump.hprof <PID>

Then, open the Heap Dump with your favourite tool. For example Eclipse MAT:

solving java.lang.OutOfMemoryError: Metaspace error java.lang.OutOfMemoryError: Metaspace

From the Heap Dump, you can look for duplicate classes, especially those loading your application classes.

The simplest way to do that, is using the OQL console. Within the OQL Console you can execute OQL queries to perform ad hoc analysis on your classes. For example, by executing the following query, you can have a list of class loaded from each Classloader:

select map(sort(map(heap.objects('java.lang.ClassLoader'), '{loader: it, count: it.classes.elementCount }'), 'lhs.count < rhs.count'), 'toHtml(it) + "
"')

solving java.lang.OutOfMemoryError: Metaspace error java.lang.OutOfMemoryError: Metaspace

This can be a precious hint to determine if a Classloader is loading an increasing number of classes.

OutOfMemoryError: Metaspace on OpenShift/Kubernetes

When using OpenJDK Image on OpenShift/Kubernetes, the default maximum value for the Metaspace is XX:MaxMetaspaceSize=100m. You might have noticed that setting this value through the JAVA_OPTIONS environment variable, doesn’t work as the default value is appended to the bottom:

VM Arguments: -Xms128m -Xmx1024m -XX:MetaspaceSize=128M -XX:MaxMetaspaceSize=256m    -XX:AdaptiveSizePolicyWeight=90 -XX:MaxMetaspaceSize=100m -XX:+ExitOnOutOfMemoryError

The correct way to set the MaxMetaspaceSize is through the GC_MAX_METASPACE_SIZE environment variable. For example, if you are using a deployment.yaml file to deploy your application with JKube, the following settings will override the default values for the MaxMetaspaceSize and MaxMetaspaceSize:

spec:
  template:
    spec:
      containers:
      - env:
        - name: JAVA_OPTIONS
          value: '-Xms128m -Xmx1024m'
        - name: GC_MAX_METASPACE_SIZE
          value: 256
        - name: GC_METASPACE_SIZE
          value: 96


Post Views:
4,684

В Java, начиная с 8 версии, появилась новая вариация OutOfMemory error : Metaspace.

Происходит это в связи с переполнением этой самой области памяти, которая является по сути эквивалентом Permanent Generation, однако может динамически расширяться.

Вопрос опытным товарищам:
Возникали ли у вас подобные ситуации в вашей практике, за исключением случаев, когда использовались сторонние библиотеки?

задан 3 дек 2018 в 0:32

Donatello's user avatar

DonatelloDonatello

3954 серебряных знака15 бронзовых знаков

Вот тут еще в 2013 году описывали работу Metaspace с примером переполнения без использования сторонних библиотек. Попробуйте, может взлетит.

ответ дан 3 дек 2018 в 7:55

zolt's user avatar

zoltzolt

1,5078 серебряных знаков15 бронзовых знаков

Выделение оперативной памяти в TLauncher

Для нормальной работы Minecraft рекомендуется выделять как можно больше памяти, особенно при использовании модов и ресурс-паков высокого разрешения. Существует несколько проблем в этом направлении, решить их просто.

Можно выделить только 1 ГБ ОЗУ в лаунчере

В настройках лаунчера (Иконка Шестерёнки -> Дополнительно) видно, что выделить можно до 1 гигабайта памяти. Всё из-за разрядности, установленной Java x32, необходимо Java x64.

1) Перед переустановкой Java, обязательно необходимо узнать, что у вас система 64 разрядная. Выполните следующие действия для определения разрядности:

Для Windows

Заходим в «Мой компьютер» -> «Свойства системы» -> находим надпись: «Тип системы» и там будет 64-bit или 32-bit.

Для Linux

Открываем Терминал (Terminal) и вводим команду uname -m , если покажется x86_64 — то у вас 64 разрядная система, если i686 или i386 — то у вас 32 разрядная.

2) Как только узнали, что у вас 64 разрядная система, приступаем к установке Java 64x. (Если у вас всё-таки 32-битная система, необходимо переустановка системы на 64-битную, при условии, что процессор поддерживает 64-битную схему.)

Для Windows

Скачиваем установщик Java 64, запускаем его и следующем инструкции (просто нажать Install). Скачать Java 64x Windows

Для Linux

Скачиваем установщик Java 64, запускаем его и следующем инструкции (просто нажать Install).

Сачать Java 64x Linux

Скачать Java 64x Linux RPM

3) После этого, в настройках можно выделить максимальное количество памяти (при создании мод-паков тоже).

Выделить память в лаунчере при 64 битной Java

Старую версию Java 32x удалять необязательно, но если в настройках продолжает отображаться только 1 гб, то удалите старую версию и установите только Java 64x.

Читайте также:
— Как установить HD скин в TLauncher
— Как установить плащ в TLauncher

Если Ваша проблема остаётся актуальной, запросите поддержку у TLauncher:

Написать разработчикам с помощью VK.com

Пишите в комментариях какой способ помог:

Играя в Minecraft и вообще, пользуясь приложениями, написанными на Java Вы не раз могли столкнуться с ошибками (исключениями). В отличие от других языков программирования, Java жёстко заточена под использование ООП, потому при возникновении ошибки бросается исключение (объект содержащий сведения под ошибке). Его можно «поймать», дабы предпринять какие-то действия (допустим, вывести в лог). В случае майнкрафта, при возникновении исключения, создаётся краш-отчёт и работа игры завершается.

Понять исключения достаточно просто и вам для этого не понадобится специальное ПО для отладки.

2017-10-03_153645.png

Полная печать исключения состоит из 3-х частей:

  1. Исключение — имя класса ошибки. Классам обычно дают понятные человеку имена, достаточно знаний английского, чтобы понять значение.
  2. Сообщение — содержит более детальное описание ошибки. Может отсутствовать.
  3. Стек вызова — отражает ход работы программы (снизу вверх). Данная информация больше полезна разработчику, дабы понять, где именно возникла ошибка. Обычному пользователю данная информация может помочь понять, с чем связана ошибка (по именам классов и вызываемым функциям — методам).

Исключения могут иметь предков, что присутствует в данном примере (после «Caused by» идёт печать исключения-предка). Если вам не понятно исключение, возможно, стоит рассмотреть его предков — они могут содержать более понятное сообщение.

В данной теме я опишу наиболее часто встречающиеся ошибки, а также, какие действия следует или вовсе не следует предпринимать. Причин у ошибок множество и это не всегда повреждённые файлы игры (чего быть в принципе не может, поскольку лаунчер проверяет файлы игры).

При возникновении ошибок не спешите бежать переустанавливать Java и игру! Java — стабильный продукт. В большинстве случаев, ошибки возникают из-за неправильной настройки ОС; ошибок сети; неправильных драйверов.

org.lwjgl.LWJGLException: Pixel format not accelerated
Недоступно аппаратное ускорение графики. Описание ошибки (англ.)

Решение: Установите последнюю версию драйвера видеокарты.

javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path validation/building failed
Не удаётся установить защищённое соединение из-за невозможности проверки SSL сертификата.

Что можно сделать:

  • Эта ошибка может возникнуть из-за использования слишком старой версии Java. Рекомендуется регулярно обновлять ПО, чтобы иметь актуальный список корневых сертификатов.
  • Виновником может быть антивирус, пытающийся «подсунуть» свой сертификат с целью прослушивания трафика. Настоятельно рекомендуется отключить в антивирусе проверку защищённых соединений (HTTPS/SSL/TLS) — это значительно снижает безопасность защищённых соединений и вызывает проблемы в работе приложений, использующие их.

java.net.SocketTimeOutException: Read timed out
Ошибка сети «время ожидания истекло». Здесь сложно установить виновника: проблема может быть как на стороне сервера, вашего провайдера или вызвана антивирусом.

Что можно сделать:

  • Отключите антивирус и попробуйте выполнить запрос снова.
  • Используйте другое подключение к интернету (другой провайдер; мобильный интернет; VPN; Wi-Fi соседей).
  • Используйте VPN для обхода блокировки (цензуры) со стороны вашего интернет-провайдера.

java.net.ConnectException: Connection timed out: connect
Ошибка сети — не удалось установить соединение с хостом. Обычно виновником данной ошибки является Firewall (брандмауэр) или отсутствие интернета.

Что можно сделать:

  • Проверьте наличие подключения к интернету.
  • Временно отключите антивирус и Firewall.

java.net.SocketException: Connection reset / Удаленный хост принудительно разорвал существующее подключение
Ошибка сети «соединение сброшено». Как и в предыдущей ошибке, проблема связана с «плохим» интернетом, либо проблемами на стороне сервера (в этом случае ошибка будет у всех). Чаще всего возникает у пользователей мобильного интернета (USB-модем). От вас никаких действий предпринимать не требуется, кроме как найти «другой интернет» или использовать VPN для обхода фильтра сайтов.

java.lang.ClassCastException: XXX cannot be cast to YYY
Ошибка в логике программы: попытка привести объект к классу, экземпляром коего объект не является.

Решение: Сообщите о проблеме разработчику программы, приложив лог ошибки.

java.io.IOException: Server returned HTTP response code: 000 for URL
Проблема на стороне веб-сервера. Стандартная библиотека Java выбрасывает исключение, если веб-сервер выдаёт, например, страницу «404 Not Found».

Решение: Сообщите о проблеме владельцу веб-сервера, URL которого указан в тексте ошибки.

java.lang.UnsatisfiedLinkError: Can’t load library:
Не удалось загрузить нативную библиотеку (скорее всего, отсутствует файл по указанному пути).

Что можно сделать:

  • Чаще всего ошибка возникает из-за отсутствия библиотек LWJGL. Почему их файлы пропадают, пока остаётся загадкой. Если пути вы видите «.redserver/natives/2.9.1/lwjgl.dll», значит надо удалить папку natives, находящуюся в .redserver, чтобы лаунчер их скачал заново.
    Неактуально: С версии 3.2 лаунчер проверяет наличие всех файлов и автоматически, при необходимости, перекачивает их.

java.lang.RuntimeException: Unknown character in
Синтаксическая ошибка в конфигурационном файле мода.

Что можно сделать:

  • Удалите указанный в ошибке файл. Мод создаст новый с настройками по умолчанию.
  • Если вам сложно удалить файл, можно сделать сброс конфигов через лаунчер. Нажмите в лаунчере на многоточие на кнопке «Играть»; выберите в меню пункт «Очистка клиента»; установите флажок возле «Сбросить конфигурацию» и запустите очистку.
  • Выполните проверку диска на наличие ошибок. Испорченные файлы могут быть признаком неисправности диска.

java.lang.NullPointerException (NPE)
Ошибка в логике программы: попытка вызвать нестатичный метод, обратиться к полю несуществующего объекта — null.

Решение: Сообщите о проблеме разработчику программы, приложив лог ошибки.

java.net.UnknownHostException
Ошибка сети: не удаётся определить IP-адрес доменного имени (в общем, проблемы с DNS).

Что можно сделать:

  • Иногда ошибка может возникать, если вы не подключены к интернету, либо же произошёл разрыв интернет-соединения. Обычно исчезает сама через небольшой промежуток времени после возобновления соединения. Если ошибка не исчезла — может помочь перезагрузка компьютера (сбрасывает кеш DNS).
  • Доступ к ресурсу заблокирован вашим провайдером. Сейчас данная проблема актуальна для украинских пользователей: используемый нами Яндекс.DNS заблокирован в этой стране. Читайте, как обойти блокировку DNS.

java.io.EOFException: Unexpected end of ZLIB input stream
Неожиданный конец файла. В данном случае — ZIP-архива. Возникает например, когда вы пытаетесь распаковать недокачанный архив.

java.net.SocketException: Address family not supported by protocol family: connect
Проблема возникает из-за неправильной настройки протокола IPv6. Если таковой не поддерживается вашим интернет-провайдером, его поддержку следует отключить.

image.png

java.lang.OutOfMemoryError
А вот это как раз «любимая» ошибка про нехватку ОЗУ. Не стоит сразу спешить выставлять память в лаунчере на максимум, потому что дальнейшие действия зависят от сообщения к ошибке:

  • Unable to create new native thread / Metaspace — в вашей системе закончились ресурсы (ОЗУ). Решается только путём завершения всех лишних программ, либо апгрейдом ПК (больше ОЗУ — больше программ можно запустить). Не забывайте, что следует использовать 64-разрядную систему.
  • Java heap space — нехватка размера heap области памяти. Увеличьте лимит памяти в настройках лаунчера.

java.lang.OutOfMemoryError:
Metaspace

Java applications are allowed to use only a limited amount of memory. The exact amount of memory your particular application can use is specified during application startup. To make things more complex, Java memory is separated into different regions, as seen in the following figure:

metaspace error

The size of all those regions, including the metaspace area, can be specified during the JVM launch. If you do not determine the sizes yourself, platform-specific defaults will be used.

The java.lang.OutOfMemoryError: Metaspace message indicates that the Metaspace area in memory is exhausted.

What is causing it?

If you are not a newcomer to the Java landscape, you might be familiar with another concept in Java memory management called PermGen. Starting from Java 8, the memory model in Java was significantly changed. A new memory area called Metaspace was introduced and Permgen was removed. This change was made due to variety of reasons, including but not limited to:

  • The required size of permgen was hard to predict. It resulted in either under-provisioning triggering java.lang.OutOfMemoryError: Permgen size errors or over-provisioning resulting in wasted resources.
  • GC performance improvements, enabling concurrent class data de-allocation without GC pauses and specific iterators on metadata
  • Support for further optimizations such as G1 concurrent class unloading.

So if you were familiar with PermGen then all you need to know as background is that – whatever was in PermGen before Java 8 (name and fields of the class, methods of a class with the bytecode of the methods, constant pool, JIT optimizations etc) – is now located in Metaspace.

As you can see, Metaspace size requirements depend both upon the number of classes loaded as well as the size of such class declarations. So it is easy to see the main cause for the java.lang.OutOfMemoryError: Metaspace is: either too many classes or too big classes being loaded to the Metaspace.

Give me an example

As we explained in the previous chapter, Metaspace usage is strongly correlated with the number of classes loaded into the JVM. The following code serves as the most straightforward example:

public class Metaspace {
	static javassist.ClassPool cp = javassist.ClassPool.getDefault();

	public static void main(String[] args) throws Exception{
		for (int i = 0; ; i++) { 
			Class c = cp.makeClass("eu.plumbr.demo.Generated" + i).toClass();
		}
	}
}

In this example the source code iterates over a loop and generates classes at the runtime. All those generated class definitions end up consuming Metaspace. Class generation complexity is taken care of by the javassist library.

The code will keep generating new classes and loading their definitions to Metaspace until the space is fully utilized and the java.lang.OutOfMemoryError: Metaspace is thrown. When launched with -XX:MaxMetaspaceSize=64m then on Mac OS X my Java 1.8.0_05 dies at around 70,000 classes loaded.

What is the solution?

The first solution when facing the OutOfMemoryError due to Metaspace should be obvious. If the application exhausts the Metaspace area in the memory you should increase the size of Metaspace. Alter your application launch configuration and increase the following:

-XX:MaxMetaspaceSize=512m

The above configuration example tells the JVM that Metaspace is allowed to grow up to 512 MB before it can start complaining in the form of OutOfMemoryError.

Another solution is even simpler at first sight. You can remove the limit on Metaspace size altogether by deleting this parameter. But pay attention to the fact that by doing so you can introduce heavy swapping and/or reach native allocation failures instead.

Before calling it a night though, be warned – more often than not it can happen that by using the above recommended “quick fixes” you end up masking the symptoms by hiding the java.lang.OutOfMemoryError: Metaspace and not tackling the underlying problem. If your application leaks memory or just loads something unreasonable into Metaspace the above solution will not actually improve anything, it will just postpone the problem.

Какие бывают типы OutOfMemoryError или из каких частей состоит память java процесса

Если вы словили OutOfMemoryError, то это вовсе не значит, что ваше приложение создает много объектов, которые не могут почиститься сборщиком мусора и заполняют всю память, выделенную вами с помощью параметра -Xmx. Я, как минимум, могу придумать два других случая, когда вы можете увидеть эту ошибку. Дело в том, что память java процесса не ограничивается областью -Xmx, где ваше приложение программно создает объекты.

image

Область памяти, занимаемая java процессом, состоит из нескольких частей. Тип OutOfMemoryError зависит от того, в какой из них не хватило места.

1. java.lang.OutOfMemoryError: Java heap space

Не хватает место в куче, а именно, в области памяти в которую помещаются объекты, создаваемые программно в вашем приложении. Размер задается параметрами -Xms и -Xmx. Если вы пытаетесь создать объект, а места в куче не осталось, то получаете эту ошибку. Обычно проблема кроется в утечке памяти, коих бывает великое множество, и интернет просто пестрит статьями на эту тему.

2. java.lang.OutOfMemoryError: PermGen space

Данная ошибка возникает при нехватке места в Permanent области, размер которой задается параметрами -XX:PermSize и -XX:MaxPermSize. Что там лежит и как бороться с OutOfMemoryError возникающей там, я уже описал подробнейшим образом тут.

3. java.lang.OutOfMemoryError: GC overhead limit exceeded

Данная ошибка может возникнуть как при переполнении первой, так и второй областей. Связана она с тем, что памяти осталось мало и GC постоянно работает, пытаясь высвободить немного места. Данную ошибку можно отключить с помощью параметра -XX:-UseGCOverheadLimit, но, конечно же, её надо не отключать, а либо решать проблему утечки памяти, либо выделять больше объема, либо менять настройки GC.

4. java.lang.OutOfMemoryError: unable to create new native thread

Впервые я столкнулся с данной ошибкой несколько лет назад, когда занимался нагрузочным тестированием и пытался выяснить максимальное количество пользователей, которые могут работать с нашим веб-приложением. Я использовал специальную тулзу, которая позволяла логинить пользователей и эмулировать их стандартные действия. На определенном количестве клиентов, я начал получать OutOfMemoryError. Не особо вчитываясь в текст сообщения и думая, что мне не хватает памяти на создание сессии пользователя и других необходимых объектов, я увеличил размер кучи приложения (-Xmx). Каково же было мое удивление, когда после этого количество пользователей одновременно работающих с системой только уменьшилось. Давайте подробно разберемся как же такое получилось.

На самом деле это очень просто воспроизвести на windows на 32-битной машине, так как там процессу выделяется не больше 2Гб.

Допустим у вас есть приложение с большим количеством одновременно работающих пользователей, которое запускается с параметрами -Xmx1024M -XX:MaxPermSize=256M -Xss512K. Если всего процессу доступно 2G, то остается свободным еще коло 768M. Именно в данном остатке памяти и создаются стеки потоков. Таким образом, примерно вы можете создать не больше 768*(1024/512)=1536 (у меня при таких параметрах получилось создать 1316) нитей (см. рисунок в начале статьи), после чего вы получите OutOfMemoryError. Если вы увеличиваете -Xmx, то количество потоков, которые вы можете создать соответственно уменьшается. Вариант с уменьшением -Xss, для возможности создания большего количества потоков, не всегда выход, так как, возможно, у вас существуют в системе потоки требующие довольно больших стеков. Например, поток инициализации или какие-нибудь фоновые задачи. Но все же выход есть. Оказывается при программном создании потока, можно указать размер стека: Thread(ThreadGroup group, Runnable target, String name,long stackSize). Таким образом вы можете выставить -Xss довольно маленьким, а действия требующие больших стеков, выполнять в отдельных потоках, созданных с помощью упомянутого выше конструктора.

Более подробно, что же лежит в стеке потока, и куда уходит эта память, можно прочитать тут.

Конечно, вам может показаться данная проблема слегка надуманной, так как большинство серверов нынче крутиться на 64-битной архитектуре, но все же считаю данный пример весьма полезным, так как он помогает разобраться из каких частей состоит память java-процесса.

3.2 Understand the OutOfMemoryError Exception

One common indication of a memory leak is the java.lang.OutOfMemoryError exception. Usually, this error is thrown when there is insufficient space to allocate an object in the Java heap. In this case, The garbage collector cannot make space available to accommodate a new object, and the heap cannot be expanded further. Also, this error may be thrown when there is insufficient native memory to support the loading of a Java class. In a rare instance, a java.lang.OutOfMemoryError may be thrown when an excessive amount of time is being spent doing garbage collection and little memory is being freed.

When a java.lang.OutOfMemoryError exception is thrown, a stack trace is also printed.

The java.lang.OutOfMemoryError exception can also be thrown by native library code when a native allocation cannot be satisfied (for example, if swap space is low).

An early step to diagnose an OutOfMemoryError exception is to determine the cause of the exception. Was it thrown because the Java heap is full, or because the native heap is full? To help you find the cause, the text of the exception includes a detail message at the end, as shown in the following exceptions.

In other cases, and in particular for a long-lived application, the message might be an indication that the application is unintentionally holding references to objects, and this prevents the objects from being garbage collected. This is the Java language equivalent of a memory leak. Note: The APIs that are called by an application could also be unintentionally holding object references.

One other potential source of this error arises with applications that make excessive use of finalizers. If a class has a finalize method, then objects of that type do not have their space reclaimed at garbage collection time. Instead, after garbage collection, the objects are queued for finalization, which occurs at a later time. In the Oracle Sun implementation, finalizers are executed by a daemon thread that services the finalization queue. If the finalizer thread cannot keep up, with the finalization queue, then the Java heap could fill up and this type of OutOfMemoryError exception would be thrown. One scenario that can cause this situation is when an application creates high-priority threads that cause the finalization queue to increase at a rate that is faster than the rate at which the finalizer thread is servicing that queue.

If this type of the OutOfMemoryError exception is thrown, you might need to use troubleshooting utilities on the operating system to diagnose the issue further. For more information about tools available for various operating systems, see Native Operating System Tools.

CompressedClassSpaceSize of 4294967296 is invalid; must be between 1048576 and 3221225472.

Note: There is more than one kind of class metadata — klass metadata and other metadata. Only klass metadata is stored in the space bounded by CompressedClassSpaceSize . The other metadata is stored in Metaspace .

Русские Блоги

Итак, обычно есть две причины этой аномалии:
1. В программе есть бесконечный цикл.
2. Программа занимает слишком много памяти, что превышает максимальное значение, установленное кучей JVM.
В первом случае вам необходимо самостоятельно проверить программный код, поэтому я не буду здесь говорить больше.
Во втором случае мы вручную расширяем настройки параметров кучи JVM. Настройка кучи JVM относится к настройке пространства памяти, которое JVM может выделить и использовать во время выполнения программы java. Когда JVM запускается, куча JVM автоматически устанавливает значение размера кучи. Обычно значение по умолчанию для начального пространства (например, -Xms) составляет 1/64 физической памяти, а максимальное пространство составляет 1/4 физической памяти. Его можно установить с помощью таких параметров, как -Xmn -Xms -Xmx, предоставляемых JVM. Вот объяснение значения каждого параметра:
-Xms: начальное значение
-Xmx: максимум
-Xmn: минимальное значение
Размер кучи не должен быть слишком маленьким или слишком большим. Если параметр слишком мал, скорость отклика программы будет ниже, потому что сборщик мусора занимает больше времени, а приложение выделяет меньше времени на выполнение. Слишком большой размер также приведет к потере места и повлияет на нормальную работу других программ. Размер кучи не должен превышать 80% доступной физической памяти. Рекомендуется установить одинаковые параметры -Xms и -Xmx, а -Xmn составляет 1/4 значения -Xmx.
Основные методы настройки следующие:
1. Этот параметр добавляется при выполнении файла класса JAVA, где className — это имя класса, который необходимо выполнить. (Включая имя пакета) Например: java -Xms32m -Xmx800m className Это не только решает проблему, но и скорость выполнения намного выше, чем когда она не установлена. Если это тест разработки, вы также можете установить его прямо в eclipse. Введите -Xms32m -Xmx800m в аргументы виртуальной машины в Eclipse -> run -arguments.
2. Вы можете изменить системные переменные среды в Windows и добавить JAVA_OPTS = -Xms64m -Xmx512m.
3. Если вы используете tomcat под окнами, вы можете добавить в C: tomcat5.5.9 bin catalina.bat (конкретный путь зависит от местоположения вашего tomcat): установить JAVA_OPTS = -Xms64m -Xmx256m (размер зависит от вашей собственной памяти) Местоположение: rem Угадайте CATALINA_HOME, если не определено Добавьте соответствующее в этой строке.
4. Если это система Linux, добавьте набор JAVA_OPTS = ’- Xms64 -Xmx512’ перед /bin/catalina.sh
Поскольку программе необходимо прочитать около 10 Вт строк записей из данных для обработки, возникает ошибка типа java.lang.OutOfMemoryError: пространство кучи Java появляется при чтении 9 Вт.
Проверка в Интернете может быть причиной того, что параметр стека JAVA слишком мал.
Согласно ответам в Интернете, существует примерно два решения:
1. Задайте переменные среды.
set JAVA_OPTS= -Xms32m -Xmx512m
можно изменить в соответствии с объемом памяти вашего компьютера, но моя проверка этого метода не решила проблему. Это может быть где еще нужно установить.

2、java -Xms32m -Xmx800m className
— добавить этот параметр при выполнении файла класса JAVA, где className — это фактическое имя класса, который должен быть выполнен. (Включая название пакета)
Это решает проблему. И скорость выполнения намного выше, чем без настройки.

Если вы можете использовать Eclispe при тестировании, вам необходимо ввести параметр -Xms32m -Xmx800m в аргументы виртуальной машины в Eclipse -> run -arguments.

java.lang.OutOfMemoryError: Java heap space

Исключение возникает при использовании программы Java для запроса большого количества данных из базы данных:
java.lang.OutOfMemoryError: Java heap space

В JVM, если 98% времени используется для сборки мусора, а доступный размер кучи меньше 2%, будет выдано это сообщение об исключении.

Настройка кучи JVM относится к настройке пространства памяти, которое JVM может выделить и использовать во время выполнения программы java.

JVM автоматически установит значение размера кучи при запуске.Его начальное пространство (-Xms) составляет 1/64 физической памяти, а максимальное пространство (-Xmx) — 1/4 физической памяти. Его можно установить с помощью таких параметров, как -Xmn -Xms -Xmx, предоставляемых JVM.
Например: java -jar -Xmn16m -Xms64m -Xmx128m MyApp.jar

Если размер кучи установлен слишком маленьким, в дополнение к этим аномальным сообщениям вы обнаружите, что скорость отклика программы снижается. Сборщик мусора занимает больше времени, а приложение выделяет меньше времени на выполнение.

Размер кучи не должен превышать 80% доступной физической памяти.Обычно для параметров -Xms и -Xmx должны быть установлены одинаковые значения, а -Xmn составляет 1/4 значения -Xmx.
Параметры размера кучи -Xms -Xmn не должны превышать размер физической памяти. В противном случае появится сообщение «Ошибка при инициализации виртуальной машины. Не удалось зарезервировать достаточно места для кучи объектов».

==========================================================
После ночи напряженной работы я наконец завершил программу замены файлов для указанной строки, но поскольку я хочу заменить слишком много файлов html для общесайтовой программы, поэтому затмение всегда заканчивается в каталоге После сообщения об исключении java.lang.OutOfMemoryError: пространство кучи Java произошел сбой.

Я подумал, что слишком поздно перерабатывать из-за частых операций, поэтому я добавил Thread.sleep (1000) после каждого цикла и обнаружил, что он умрет в этом каталоге, поэтому я изменил 1000 на 5000 или умер там. Я думаю, что это может быть не так просто перерабатывать, возможно, JVM Sun просто не выпускает для этой ситуации.
Затем я добавил -Xmx256M к параметру запуска, на этот раз все было нормально.

Подумав об этом, я до сих пор мало что знаю о принципах сборки мусора, я проверил это в Интернете и нашел несколько хороших статей.

Также существуют: Управление кучей Java — сборка мусора. Следует отметить следующие моменты, которые могут использоваться в качестве рекомендаций при написании программ:

(1) Не пытайтесь предполагать время, когда происходит сборка мусора, причем все это неизвестно. Например, временный объект в методе становится бесполезным после вызова метода, и его память может быть освобождена в это время.

(2) Java предоставляет несколько классов, которые занимаются сборкой мусора, и предоставляет способ принудительного вызова функции сборки мусора System.gc (), но это также ненадежный метод. Java не гарантирует, что сборка мусора будет запускаться каждый раз при вызове этого метода. Она просто отправляет такой запрос в JVM. Неизвестно, выполняется ли сборка мусора на самом деле.

(3) Выберите подходящий вам сборщик мусора. Вообще говоря, если система не предъявляет особых требований к производительности, вы можете использовать параметры JVM по умолчанию. В противном случае вы можете рассмотреть возможность использования целевых сборщиков мусора.Например, инкрементные сборщики больше подходят для систем с высокими требованиями к работе в реальном времени. Система имеет более высокую конфигурацию и больше простаивающих ресурсов, вы можете рассмотреть возможность использования параллельного сборщика меток / разверток.

(4) Ключевая и сложная проблема — это утечки памяти. Хорошие навыки программирования и строгое отношение к программированию всегда являются самыми важными. Не позволяйте небольшой собственной ошибке вызвать большую дыру в памяти.

(5) Освободите ссылки на бесполезные объекты как можно скорее.
Когда большинство программистов используют временные переменные, они автоматически устанавливают для ссылочной переменной значение null после выхода из активной области (области), что означает, что сборщик мусора будет собирать объект. Вы должны обратить внимание на то, отслеживается ли объект, на который указывает ссылка, если да, удалите прослушиватель, а затем назначьте нулевое значение.

Другими словами, лучше контролировать операции частого обращения к памяти и освобождения памяти самостоятельно, но метод System.gc () может быть неприменим. Лучше использовать finalize для принудительного выполнения или написать свой собственный метод finalize.

Я обнаружил ошибку TOMCAT: java.lang.OutOfMemoryError: пространство кучи Java, поэтому я проверил информацию и нашел решение:
If Java runs out of memory, the following error occurs:
Exception in thread “main” java.lang.OutOfMemoryError: Java heap space
Java heap size can be increased as follows:

java -Xms -Xmx
Defaults are:
java -Xms32m -Xmx128m

Если вы используете выигрыш
/tomcat/bin/catalina.bat плюс следующая команда:
set JAVA_OPTS=-Xms32m -Xmx256m

Если вы используете unix / linux
/tomcat/bin/catalina.sh плюс следующая команда:
JAVA_OPTS=»-Xms32m -Xmx256m»

инструмент просмотра и анализа памяти jvm
В отрасли существует множество мощных инструментов для профилей Java, таких как Jporfiler и yourkit. Я не хочу говорить об этих платных вещах. Я хочу сказать, что сама java обеспечивает большой мониторинг памяти. Маленькие инструменты, перечисленные ниже инструменты — лишь небольшая часть. Все еще довольно интересно внимательно изучить инструменты jdk 🙂

1: вывод журнала gc

-verbose: gc и -XX: + PrintTenuringDistribution и т. д.

Код коллекции HTML-кода
Usage:
jmap -histo (to connect to running process and print histogram of java object heap
jmap -dump: (to connect to running process and dump java heap)
dump-options: format=b binary default file=
dump heap to
Example: jmap -dump:format=b,file=heap.bin

jmap -dump:file=c:dump.txt 340

Обратите внимание, что 340 — это pid java-процесса моей машины. Размер выгруженного файла превышает 10 мегабайт, и я только что открыл tomcat и запустил очень простое приложение без какого-либо доступа. Его можно представить на большом и загруженном сервере. , Насколько большим должен быть файл дампа? Что вам нужно знать, так это то, что информация о файле дампа очень примитивна и определенно не подходит для просмотра людьми напрямую, а содержимое, отображаемое jmap -histo, слишком простое, например, оно только показывает, сколько памяти занимают определенные типы объектов и количество этих объектов. , Но нет более подробной информации, например, кто создал эти объекты. Итак, какая польза от файла дампа? Конечно полезно, потому что есть инструмент для анализа файла дампа памяти jvm.

6: анализатор памяти eclipse

S0 S1 E O P YGC YGCT FGC FGCT GCT
54.62 0.00 42.87 43.52 86.24 1792 5.093 33 7.670 12.763

S0 S1 E O P YGC YGCT FGC FGCT GCT
54.62 0.00 42.87 43.52 86.24 1792 5.093 33 7.670 12.763

S0: Зона susvivor0 нового поколения, коэффициент использования площадей 54 . 62%

S1: область susvivor1 нового поколения, коэффициент использования пространства составляет 0,00% (поскольку второй второстепенный сбор не был выполнен)

Многие разработчики видели проблему «java.lang.OutOfMemoryError: PermGen space» в своих системах. Это часто вызвано утечками памяти, связанными с загрузчиками классов и созданием новых загрузчиков классов, которые обычно происходят, когда код развернут в горячем режиме. По сравнению с формальными продуктами эта проблема чаще встречается на компьютере разработчика. Наиболее распространенная «проблема» в продукте — слишком низкое значение по умолчанию. Обычное решение — установить его на 256 МБ или выше.

Вечное поколение

Полное имя пространства PermGen — пространство Permanent Generation, которое относится к области постоянного хранения памяти. Поговорим о том, почему память полезна: эта часть используется для хранения информации о классе и мета-классе. Класс помещается в область пространства PermGen при загрузке. Он отличается от области кучи, где хранится экземпляр, поэтому, если ваше приложение будет загружать много CLASS, вполне вероятно, что возникнет ошибка пространства PermGen. Эта ошибка распространена, когда веб-сервер предварительно компилирует JSP.

Существует много типов JVM, таких как Oralce-Sun Hotspot, Oralce JRockit, IBM J9, Taobao JVM (Taobao хороший вид!) И так далее. Конечно, лидером боевых искусств является Hotspot, это не спор.Следует отметить, что пространство PermGen доступно только в Oracle-Sun HotspotJRockit и J9 не имеют этой области.

Постоянное поколение содержит все данные в виртуальной машине, которые могут быть получены с помощью отражения, такие как объекты класса и метода. Разные виртуальные машины Java могут совместно использовать классы, поэтому постоянное поколение делится на область только для чтения и область чтения-записи.

Метаданные, используемые JVM для описания классов и методов, используемых в приложении, также сохраняются в постоянном поколении. Сколько места для генерации будет использовать JVM, зависит от того, сколько классов использует приложение. Кроме того, классы и методы в библиотеке Java SE также хранятся здесь.

Если JVM обнаружит, что некоторые классы больше не нужны, она восстановит (выгрузит) эти классы и освободит их пространство для использования другими классами. Полный GC восстановит длительное поколение.

  • Область хранения метаданных класса в JVM в куче Java.
  • Внутреннее представление в виртуальной машине HotSpot, соответствующее классу Java, также хранится здесь.
  • Информация об иерархии классов, поля, имена.
  • Метод компиляции информации и байт-код.
  • переменная
  • Постоянный пул и разрешение символов

Постоянный размер поколения

  • Его верхний предел — MaxPermSize, по умолчанию — 64M.
  • Смежные области в куче Java: если они хранятся в несмежном пространстве кучи, очень сложно и занимает много времени, чтобы найти ссылки, которые сохраняются для новых объектов. Таблица карт (таблица карт) является своего рода набором памяти (Remembered Set), который используется для записи изменений общих указателей объектов (упс) в процессе генерации памяти.
  • После использования постоянного прокси будет выдано исключение OutOfMemoryError «Пространство PermGen». Решение: приложение очищает ссылки для запуска выгрузки класса, увеличивает размер MaxPermSize.
  • Сколько требуется постоянного пространства генерации, зависит от количества классов, размера метода и размера константного пула.

Почему удалить постоянное поколение

  • Его размер фиксируется при запуске — его сложно настроить. -XX: MaxPermSize, насколько лучше?
  • Внутренний тип HotSpot также является Java-объектом: он может перемещаться в Full GC, в то же время он непрозрачен для приложения и не является строго типизированным, его трудно отслеживать и отлаживать, а также необходимо хранить метаданные метаданных (мета-метаданные).
  • Упростить полный сборщик мусора: у каждого сборщика есть специальный итератор метаданных.
  • Данные класса могут быть освобождены одновременно без GC-паузы.
  • Некоторые улучшения, которые изначально были ограничены постоянным поколением, могут быть реализованы в будущем.

Так куда же делись метаданные для JVM?

Элемент пространства (Метапространство)

Пространство постоянного поколения полностью удалено, и оно заменено областью, названной metaspace. После удаления постоянного поколения очевидно, что JVM игнорирует два параметра PermSize и MaxPermSize, и вы больше не видите исключение java.lang.OutOfMemoryError: PermGen error.

HotSpot JVM в JDK 8 теперь использует локальную память для представления метаданных класса. Эта область называется метапространством.

Особенности метапространства:

  • Воспользуйтесь всеми преимуществами спецификации языка Java: жизненный цикл класса и связанных метаданных соответствует загрузчику классов.
  • Каждый загрузчик имеет выделенное место для хранения
  • Только линейное распределение
  • Не перерабатывает класс отдельно
  • Экономьте время сканирования и сжатия ГХ
  • Положение объектов в метапространстве фиксировано
  • Если GC обнаружит, что определенного загрузчика классов больше нет в живых, он освободит все пространство.

Модель распределения памяти в метапространстве

  • Большая часть пространства метаданных выделяется из локальной памяти
  • Класс, используемый для описания метаданных класса, также был удален
  • Разделенные метаданные выделяют несколько пространств виртуальной памяти
  • Каждому загрузчику классов назначается список блоков памяти. Размер блока зависит от типа загрузчика классов, блок загрузчика классов, соответствующий солнцу / отражению / прокси, будет меньше
  • Возврат блока памяти, свободный список блокировки памяти
  • Как только данные в метапространстве очищены, пространство в виртуальной памяти будет восстановлено
  • Стратегии уменьшения фрагментации

Давайте посмотрим, как JVM выделяет пространство виртуальной памяти для метаданных

Вы можете увидеть, как распределяется пространство виртуальной памяти (vs1, vs2, vs3) и как распределяются блоки памяти загрузчика классов. CL — это сокращение от Class Loader.

Понимать _mark и _klass указатели

Чтобы понять картинку ниже, вы должны выяснить, что это за указатели.

В JVM каждый объект имеет указатель на свой собственный класс, но этот указатель указывает только на определенный класс реализации, а не на интерфейс или абстрактный класс.

Для 32-битной JVM:

_mark: 4 байта константы

_klass: указывает на второе поле в макете памяти 4-байтового объекта указателя класса (_klass, в 32-битной JVM, смещение от позиции объекта в памяти равно 4, а 64-битное равно 8) Является ли определение класса объекта в памяти.

64-битная JVM:

_mark: 8-байтовая константа

_klass: 8-байтовый указатель на класс

64-битная JVM с включенным сжатием указателей: _mark: 8-байтовая константа

_klass: 4-байтовый указатель на класс

Расположение памяти объектов Java

Сжатый указатель класса Space

Эта область существует только в том случае, если сжатие указателя класса включено на 64-разрядных платформах. Для 64-битных платформ для сжатия размера указателя _klass в объекте JVM вводится пространство указателя сжатого класса (пространство указателя сжатого класса).

Расположение памяти после сжатия указателей

Сжатие указателя

  • Открыт по умолчанию на 64-битных платформах
  • Используйте -XX: + UseCompressedOops для сжатия указателей на объекты. «Упс» относится к обычным указателям на объекты («обычным» указателям на объекты). Указатель объекта в куче Java будет сжат до 32 бит. Использовать базовый адрес кучи (если куча находится в памяти с низким объемом 26 ГБ, базовый адрес равен 0)

  • Используйте параметр -XX: + UseCompressedClassPointers для сжатия указателей классов.

  • Указатель на метаданные класса в объекте будет сжат до 32 бит

  • Пространство сжатия указателя класса будет иметь базовый адрес

Разница между мета-пространством и указателем как пространство сжатия

  • Пространство сжатия указателя класса содержит только метаданные класса, такие как InstanceKlass, ArrayKlass, которые вступают в силу только при включенной опции UseCompressedClassPointers. Для повышения производительности здесь также хранится таблица виртуальных методов в Java. Какие типы метаданных хранятся здесь?

  • Метапространство содержит другие относительно большие метаданные класса, такие как методы, байтовые коды и пулы констант.

Настройка метапространства

Используйте параметр -XX: MaxMetaspaceSize, чтобы установить максимальное значение метапространства. По умолчанию верхний предел отсутствует, то есть, каков верхний предел памяти вашей системы. Параметр -XX: MetaspaceSize указывает начальный размер метапространства. Если он не указан, метаскоп будет динамически корректировать размер в соответствии с потребностями среды выполнения приложения.

Тюнинг MaxMetaspaceSize

  • -XX:MaxMetaspaceSize={unlimited}
  • Размер метапространства ограничен памятью вашей машины
  • Ограничьте объем памяти, используемый метаданными класса, чтобы избежать переключения виртуальной памяти и сбоя выделения локальной памяти. Если вы подозреваете, что загрузчик классов протекает, вы должны использовать этот параметр: на 32-разрядных компьютерах, если адресное пространство может быть исчерпано, этот параметр также должен быть установлен.
  • Первоначальный размер метапространства составляет 21M — это начальная максимальная отметка ГХ. Если он превышает этот размер, для восстановления класса будет использоваться полный ГХ.
  • Если GC слишком часто после запуска, установите это значение выше
  • Может быть установлен в тот же размер, что и постоянное поколение, чтобы отложить время выполнения GC

Настройка CompressedClassSpaceSize

  • Работает только если включен -XX: + UseCompressedClassPointers
  • -XX:CompressedClassSpaceSize=1G
  • Так как этот размер фиксируется при запуске, лучше установить его больше.
  • Не устанавливайте его, если вы его не используете
  • Последующая JVM может позволить этой области динамически расти. Это не обязательно должна быть непрерывная область, если она достижима от базового адреса, больше метаинформации класса может быть возвращено в метапространство, размер пространства будет автоматически установлен на основе значения PredictedLoadedClassCount в будущем

Некоторые инструменты в метапространстве

  • jmap -permstat был изменен на jmap -clstats. Он используется для печати статистики загрузчика классов кучи Java. Для каждого загрузчика классов он выведет свое имя, будь то живой, адрес, загрузчик родительского класса, а также количество и размер загруженных классов. Кроме того, количество и размер резидентных строк (интернов) также будут напечатаны.
  • jstat -gc, эта команда выводит информацию метапространства вместо постоянной генерации
  • jcmd GC.class_stats предоставляет подробную информацию о размере метаданных класса. Вам нужно добавить опцию -XX: + UnlockDiagnosticVMOptions при запуске программы с помощью этой функции.

Улучшить производительность GC

Если вы понимаете концепцию metaspace, легко обнаружить, что производительность GC была улучшена.

  • В Full GC указатели, метаданные которых указывают на метаданные, больше не нуждаются в сканировании. Многие сложные коды сканирования метаданных (особенно в CMS) были удалены.
  • В метапространстве есть только несколько указателей на кучу Java. Это включает в себя: указатели на экземпляры java / lang / Class в метаданных класса, указатели на коллекции java / lang / Class в метаданных класса массива.
  • Нет затрат на сжатие метаданных
  • Уменьшено сканирование корневых объектов (больше не сканируется словарь загруженных классов и других внутренних хеш-таблиц на виртуальной машине)
  • Сокращено время Full GC
  • В переработчике G1 классы могут быть выгружены после завершения фазы одновременной маркировки

Метапространство в java8 суммируется следующим образом:

Состояние пермского пространства

Все это пространство памяти будет удалено.

Параметры JVM: PermSize и MaxPermSize игнорируются, и выдается предупреждение (если эти два параметра установлены при включении).

Модель распределения памяти в метапространстве

Большая часть метаданных класса размещается в локальной памяти.

«Классы», используемые для описания метаданных класса, были удалены.

Метапространственная емкость

По умолчанию метаданные класса ограничены только доступной локальной памятью (емкость зависит от объема виртуальной памяти, доступной для 32-разрядных или 64-разрядных операционных систем).

Новый параметр (MaxMetaspaceSize) используется для ограничения размера локальной памяти, выделяемой метаданным класса. Если этот параметр не указан, метаскоп будет динамически корректироваться по мере необходимости во время выполнения.

Metaspace сборка мусора

Сборка мусора для классов зомби и загрузчиков классов будет выполняться, когда использование метаданных достигнет значения, установленного параметром «MaxMetaspaceSize».

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

Влияние кучи памяти Java

Некоторые разные данные были перемещены в пространство кучи Java. После обновления до JDK8 вы увидите, что пространство кучи Java увеличилось.

Метапространственный мониторинг

Использование метапространства может быть получено из подробного журнала GC HotSpot 1.8.

Два инструмента, Jstat и JVisualVM, были обновлены при тестировании с версией b75, но вы все еще можете увидеть внешний вид старого пространства PermGen.

Вышесказанное было полностью объяснено теоретически, давайте рассмотрим новое пространство памяти через программу «утечки» …

Сравнение PermGen и Metaspace во время выполнения

Чтобы лучше понять поведение во время выполнения пространства памяти Metaspace,

Будут протестированы следующие сценарии:

  1. Используйте JDK1.7 для запуска программ на Java, отслеживания и исчерпания объема памяти PermGen по умолчанию, равного 85 МБ.

  2. Используйте JDK1.8 для запуска программ на Java и отслеживания процесса динамического роста и сбора мусора в новом пространстве памяти Metaspace.

  3. Используйте JDK1.8 для запуска Java-программы и имитации исчерпания пространства памяти Metaspace объемом 128 МБ, установленного параметром «MaxMetaspaceSize».

Сначала создан код, который имитирует PermGen OOM

  1. public class ClassA {  
  2.  public void method(String name) {  
  3.   // do nothing  
  4.  }  
  5. }  

Выше приведен простой ClassA, скомпилируйте его в байт-код класса и поместите его в D: / classes, используйте URLClassLoader для загрузки этого типа в тестовый кодВышеупомянутый класс скомпилирован в класс

  1. /**  
  2. * Моделирование PermGen OOM 
  3.  * @author benhail  
  4.  */ 
  5. public class OOMTest {  
  6.     public static void main(String[] args) {  
  7.         try {  
  8.             // подготовить URL 
  9.             URL url = new File(«D:/classes»).toURI().toURL();  
  10.             URL[] urls = {url};  
  11.             // Получить интерфейс JMX для загрузки типов 
  12.             ClassLoadingMXBean loadingBean = ManagementFactory.getClassLoadingMXBean();  
  13.             // Используется для загрузчика классов кэша 
  14.             List<ClassLoader> classLoaders = new ArrayList<ClassLoader>();  
  15.             while (true) {  
  16.                 // Загружаем тип и кешируем экземпляр загрузчика классов 
  17.                 ClassLoader classLoader = new URLClassLoader(urls);  
  18.                 classLoaders.add(classLoader);  
  19.                 classLoader.loadClass(«ClassA»);  
  20.                 // Отображение информации о количестве (количество загруженных типов, количество допустимых типов и количество выгруженных типов) 
  21.                 System.out.println(«total: « + loadingBean.getTotalLoadedClassCount());  
  22.                 System.out.println(«active: « + loadingBean.getLoadedClassCount());  
  23.                 System.out.println(«unloaded: « + loadingBean.getUnloadedClassCount());  
  24.             }  
  25.         } catch (Exception e) {  
  26.             e.printStackTrace();  
  27.         }  
  28.     }  
  29. }  

Параметры виртуальной машины устанавливаются следующим образом:-verbose -verbose:gc

Параметр -verbose устанавливается для получения информации о типах загрузки и выгрузки

Установка -verbose: gc — получить информацию о сборке мусора.

JDK 1.7 @ 64-bit — тест исчерпания PermGen

Пространство по умолчанию для PermGen в Java1.7 составляет 85 МБ (или может быть указано с помощью -XX: MaxPermSize = XXXm)

Это можно увидеть на скриншоте JVisualVM выше: после загрузки более 60 000 классов PermGen исчерпан. Мы также можем наблюдать процесс истощения через вывод программы и GC.

Вывод программы (извлеченная часть)

  1. ……  
  2. [Loaded ClassA from file:/D:/classes/]  
  3. total: 64887 
  4. active: 64887 
  5. unloaded: 0 
  6. [GC 245041K->213978K(536768K), 0.0597188 secs]  
  7. [Full GC 213978K->211425K(644992K), 0.6456638 secs]  
  8. [GC 211425K->211425K(656448K), 0.0086696 secs]  
  9. [Full GC 211425K->211411K(731008K), 0.6924754 secs]  
  10. [GC 211411K->211411K(726528K), 0.0088992 secs]  
  11. ……………  
  12. java.lang.OutOfMemoryError: PermGen space 

JDK 1.8 @ 64-битный тест на динамическое изменение размера Metaspace

Java Metaspace space: не ограничено (по умолчанию)

Как вы можете видеть на скриншоте выше, JVM Metaspace динамически расширяется, а использование локальной памяти увеличено с 20 МБ до 646 МБ, чтобы удовлетворить растущий спрос на память данных классов в программе. Мы также можем наблюдать событие сборки мусора JVM, пытающимся уничтожить мертвый класс или объект загрузчика классов. Однако из-за утечки нашей программы у JVM нет другого выбора, кроме как динамически расширять пространство памяти Metaspace. Программа загружает более 100 000 классов без событий OOM.

JDK 1.8 @ 64-bit — ограниченный тест Metaspace

Пространство метапространства Java: 128 МБ (-XX: MaxMetaspaceSize = 128 м)

Это можно увидеть на скриншоте JVisualVM выше: после загрузки более 20 000 классов Metaspace исчерпан, очень похоже на среду выполнения JDK1.7. Мы также можем наблюдать процесс истощения через вывод программы и GC. Еще одним интересным явлением является то, что зарезервированное использование собственной памяти более чем в два раза превышает установленный максимальный размер. Это может указывать на то, что, если возможно, вы можете точно настроить стратегию емкости метапространства, чтобы не тратить локальную память.

Следующее исключение видно из вывода программы Java.

  1. [Loaded ClassA from file:/D:/classes/]  
  2. total: 21393 
  3. active: 21393 
  4. unloaded: 0 
  5. [GC (Metadata GC Threshold) 64306K->57010K(111616K), 0.0145502 secs]  
  6. [Full GC (Metadata GC Threshold) 57010K->56810K(122368K), 0.1068084 secs]  
  7. java.lang.OutOfMemoryError: Metaspace 

Когда MaxMetaspaceSize установлен, память этого пространства будет по-прежнему исчерпана, что, в свою очередь, вызывает ошибку «java.lang.OutOfMemoryError: Metadata space». Поскольку утечки загрузчиков классов все еще существуют, и Java, как правило, не хочет использовать собственную память бесконечно, представляется разумным установить ограничение, аналогичное MaxPermSize.

резюме

  1. Было ли это необходимо или нет раньше, JVM будет использовать это пространство … Если настройка слишком мала, JVM умрет, а если настройка слишком большая, эта память будет потрачена впустую JVM. Теоретически, теперь вы можете полностью игнорировать это, потому что JVM автоматически адаптируется к «подходящему размеру» во время выполнения;
  2. Улучшите производительность Full GC. Во время Full GC нет необходимости сканировать метаданные и указатели метаданных, не стоит недооценивать эти несколько наносекунд;
  3. Скрытая опасность состоит в том, что если в программе есть утечка памяти, как, например, в OOMTest, постоянное расширение пространства метапространства приведет к нехватке памяти машины, поэтому необходимо провести необходимую отладку и мониторинг.

резюме

  • Метаданные в Hotspot теперь хранятся в пространстве метаданных. Жизненный цикл блоков памяти в mmap такой же, как у загрузчиков классов.
  • Сжатое пространство указателя класса (Сжатое пространство указателя класса) по-прежнему имеет фиксированный размер, но оно имеет больший размер
  • Параметры могут быть настроены, но это не обязательно.
  • Другие оптимизации и новые функции могут быть добавлены в будущем. Например, обмен данными между классами приложений, оптимизация GC нового поколения, утилизация G1 для утилизации классов, уменьшение размера метаданных и объема памяти внутренних объектов JVM.

0 0 голоса
Рейтинг статьи
Подписаться
Уведомить о
guest

0 комментариев
Старые
Новые Популярные
Межтекстовые Отзывы
Посмотреть все комментарии

А вот еще интересные материалы:

  • Яшка сломя голову остановился исправьте ошибки
  • Ясность цели позволяет целеустремленно добиваться намеченного исправьте ошибки
  • Ясность цели позволяет целеустремленно добиваться намеченного где ошибка
  • Произошла ошибка при загрузке скетча avrdude stk500 recv programmer is not responding
  • Произошла ошибка при загрузке скетча arduino uno