Старый выпуск JaxB и JDK8 Metaspace OutOfMemory
Мы работаем над бизнес-приложением (1 миллион + LOC), разработанным более 10 лет назад. При переключении на JDK8 у нас возникает проблема с метапространством JDK8. Похоже, это связано с версией JaxB, на которую ссылается com.sun.xml.ws:webservices-rt:1.4 (Metro 1.4). Из-за интенсивного связывания в приложении и унаследованного создания классов / экземпляров через JaxB нелегко переключать на лету старые библиотеки.
В настоящее время мы исследуем эту проблему. Мы создали образец программы, которая воспроизводит это поведение:
import java.io.ByteArrayInputStream;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Unmarshaller;
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlRootElement;
@XmlRootElement
public class X
{
private static final String XML = "<?xml version=\"1.0\" encoding=\"UTF-8\"?><x test=\"test\" />";
@XmlAttribute
String test;
public static void main( String[] args ) throws JAXBException, InterruptedException
{
System.out.println("start");
while ( true )
{
JAXBContext jc = JAXBContext.newInstance( X.class );
Unmarshaller unmarshaller = jc.createUnmarshaller();
X object = (X) unmarshaller.unmarshal( new ByteArrayInputStream( XML.getBytes() ) );
System.out.println( object.test );
}
}
}
JDK7 поддерживает чистоту PermGenSpace. (Моделируется с 16M PermGen)Память бега с JDK7
Используя JDK8, приложение работает медленно до исключения OOM. VisualVM перехватывает исключение и поддерживает максимальный объем доступного Metaspace. Даже здесь он застревает через некоторое время, работая на макс. (Моделируется с 16M Metaspace)Память бега с JDK8
У кого-нибудь есть идеи, как настроить устаревшее поведение сборщиков мусора, чтобы мы не сталкивались с проблемами нехватки памяти? Или у вас есть другие идеи, как решить эту проблему?
Благодарю.
edit1:Запустите параметры JDK7:
-XX:+TraceClassLoading -XX:+TraceClassUnloading -XX:MaxPermSize=16M -XX:PermSize=1M -XX:+UseParallelOldGC -XX:+HeapDumpOnOutOfMemoryError
=> Не создаются дампы кучи
Запустите параметры JDK8:
-XX:+TraceClassLoading -XX:+TraceClassUnloading -XX:MaxMetaspaceSize=16M -XX:MetaspaceSize=1M -XX:+UseParallelOldGC -XX:+HeapDumpOnOutOfMemoryError
=> дампы кучи генерируются во время работы.
Доступная память VisualVM не отображает реальное максимальное значение метапространства. Если не ограничено, то пространство мета-области постоянно увеличивается, пока не будет превышен объем памяти.
редактировать 2:
Я перепробовал все доступные сборщики мусора для JDK8. У них у всех одна и та же проблема.
редактировать 3:
Решение путем замены библиотек в нашем реальном приложении затруднено из-за сильной связи между JAXB и несколькими модулями нашего приложения. Поэтому для краткосрочного запуска необходимо исправить поведение сборщика мусора. В долгосрочной перспективе исправление проппера уже запланировано.