Java 8: почему размер метапространства увеличивается, а количество загруженных классов остается прежним?

В нашем приложении, работающем на Jdk 8, мы используем VisualVM для отслеживания использования загруженных классов и использования метапространства.

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


person longliveenduro    schedule 19.06.2015    source источник
comment
Думаю, пока количество загруженных классов не изменится, количество фактически используемого кода может еще возрасти…   -  person Holger    schedule 19.06.2015
comment
Хм, я не понимаю, что вы имеете в виду. Код классов уже есть, что там еще должно быть?   -  person longliveenduro    schedule 19.06.2015
comment
Как вы думаете, JVM хранит классы в оперативной памяти так же, как они находятся на вашем жестком диске? Метаинформация является результатом анализа или, в более общем смысле, обработки содержимого файла класса, и эта работа (или ее части) может быть отложена до тех пор, пока метод не будет действительно использован.   -  person Holger    schedule 19.06.2015
comment
Ах, ты прав. Может быть, туда идет и нативный код, скомпилированный Hotspot?   -  person longliveenduro    schedule 22.06.2015
comment
Приятно читать для компиляции в собственный код здесь: stackoverflow.com/questions/15020152/   -  person longliveenduro    schedule 23.06.2015
comment
Не уверен в этом. Но я знаю, что скомпилированный код идет в регион CodeCache, так что ничего общего с MetaSpace. Используете ли вы много отражений (или фреймворк, например, Spring)? Может быть метаинформация о прокси (дескрипторы методов и т. д.), хранящаяся в Metaspace, которая не считается загруженным классом.   -  person mabi    schedule 20.11.2015


Ответы (2)


Пока ваша программа работает, некоторые части вашего кода могут быть определены JIT-компилятором HotSpot как "горячие". Это приведет к тому, что эти части будут преобразованы/скомпилированы в собственный код, а также в него может быть встроен какой-то другой код. Это собственное представление кода должно куда-то идти, и оно находится там же, где и другие метаданные класса — в метапространстве.

Это объясняет непрерывный рост, который вы наблюдаете: горячие части определяются с течением времени с использованием простой метрики того, сколько раз этот фрагмент кода выполнялся. Со временем все больше и больше фрагментов кода будут подвергаться JIT-компиляции, поскольку они будут достигать порога, установленного -XX:CompileThreshold (по умолчанию 10000)

person Vyacheslav Tverskoy    schedule 09.08.2016

я не уверен, но здесь (http://java.dzone.com/articles/java-8-permgen-metaspace) я финансирую это

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

возможно, это причина увеличения размера метапространства.

person mafahand    schedule 24.06.2015
comment
В ОП конкретно говорится, что количество загруженных классов больше не увеличивается. Так мертв или нет, общая сумма должна быть стабильной. - person mabi; 20.11.2015