Краткое описание проблемы: При добавлении значений в hashmap после преобразования xslt в шаблоны с использованием библиотеки saxon 9.6 HE выделение кучи увеличивается до 330 МБ, что составляет почти 70% кучи (Xmx512 и Xms32). Когда в корзину добавляется больше товаров, она набирает 512 баллов и уходит в OOM, генерируя файлы phd и javacore.
Что мы пробовали: Когда мы использовали версию Saxon 9.9 HE, она экономила около 30 МБ вобщая куча, но она все еще находится на уровне 300 МБ
Цель:
1) Goal is to reduce the memory footprint.
2) Is there any fine tuning as per saxon libraries to reduce this huge heap for the transformed objects
3) We wouldn't want to remove those hashmaps from memory as those templates are needed for faster printing at the end of a cart transaction (like in a point of sale system) - hence we haven't used the getUnderlyingController.clearDocumentPool() in saxon;
Детали кода:
Саксонская инициализация в конструкторе
package com.device.jpos.posprinter.receipts;
import java.util.HashMap;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Templates;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.TransformerFactory;
import net.sf.saxon.TransformerFactoryImpl;
import com.device.jpos.posprinter.receipts.saxon.SaxonFunctions;
public class ReceiptXSLTTemplateManager
{
private HashMap<String, String> xsltTemplates = null;
private HashMap<String, Templates> xsltTransTemplates = null;
private TransformerFactory transformerFact = null;
public ReceiptXSLTTemplateManager( String xsltProcessor )
{
this.xsltProcessor = xsltProcessor;
setTransformerFactory();
xsltTemplates = new HashMap<String, String>();
xsltTransTemplates = new HashMap<String, Templates>();
// create an instance of TransformerFactory
transformerFact = javax.xml.transform.TransformerFactory.newInstance();
if ( transformerFact instanceof TransformerFactoryImpl )
{
TransformerFactoryImpl tFactoryImpl = (TransformerFactoryImpl) transformerFact;
net.sf.saxon.Configuration saxonConfig = tFactoryImpl.getConfiguration();
SaxonFunctions.register( saxonConfig );
}
}
}
Преобразование xslt и добавление в hashmap
public boolean setTransformer( String name )
{
if ( xsltTemplates.containsKey( name ) )
{
StringReader xsltReader = new StringReader( xsltTemplates.get( name ) );
javax.xml.transform.Source xsltSource = new javax.xml.transform.stream.StreamSource( xsltReader );
try
{
Templates transTmpl = transformerFact.newTemplates( xsltSource );
xsltTransTemplates.put( name, transTmpl );
return true;
}
catch ( TransformerConfigurationException e )
{
logger.error( String.format( "Error creating XSLT transformer for receipt type = %s.", name ) );
}
}
else
{
logger.error( String.format( "Error creating XSLT transformer for receipt type = %s.", name ) );
}
return false;
}
Итак, хотя шаблоны xsl имеют размердиапазон от 200 КБ до 500 КБ, при преобразовании их объем в памяти составляет от 5 до 15 МБ. У нас есть 45 таких файлов, и в целом это потребляет почти 70% кучи JVM. В сочетании с другими операциями, которые используют память кучи, результатом является ошибка OutOfMemory от JVM.
Выход анализатора памяти из файла phd (ссылка на изображение):
Анализатор памяти, отображающий записи хеш-карты и преобразование s9api
Выход анализатора памяти из файла phd (ссылка на изображение)
Детализированные записи хэш-карты (изображениессылка)
У нас есть следующие вопросы: 1) Почему шаблон размером от 200 КБ до 500 КБ на диске занимает от 5 МБ до 15 МБ в памяти? после трансформации? 2) Что можно оптимизировать в том, как создаются шаблоны, прежде чем помещать их в hashmap с помощью saxon 9.6 HE или мы должны использовать другие выпуски saxon особым образом, чтобы преодолеть эту проблему с памятью.
Пожалуйста, сообщите. Спасибо за ваше драгоценное время !!