我面临一个我无法解决的问题。
我正在使用hibernate进行批量插入,一切正常,它应该配置,它的批处理插入,我检查了mysql日志以查看说明,但问题是,即使我刷新会话,它不释放内存,只是一点点,我使用配置文件检查并且所有内存都被HashMap保留,即使我清除了这个哈希映射。
查看下面的代码。
long contador = 0;
final int NUMERO_REGISTROS_GRAVAR = 5000;
Map<String, ContatoBean> mapaContatos = new HashMap<>(NUMERO_REGISTROS_GRAVAR);
final Reader inputStreamReader = new InputStreamReader(new BufferedInputStream(stream));
final String nomeTemplate = parametros.get("cmpTemplateMailing");
final MailingTemplateBean mailingTemplate = MailingService.getInstance().getMailingTemplate(nomeTemplate);
MailingFactory mailingFactory = new MailingFactory(mailingTemplate);
Session ss = HibernateUtil.getCurrentSession();
try (CSVParser csvParser = CSVFormat
.newFormat(';')
.withHeader(mailingFactory.getCabecalho())
.withSkipHeaderRecord(true)
.parse(inputStreamReader))
{
Iterator<CSVRecord> iterator = csvParser.iterator();
MailingBean mailing = new MailingBean();
mailing.setNmNome(nomeArquivo.substring(0, nomeArquivo.lastIndexOf(".")));
mailing.setDsDescricao(parametros.get("descricao") != null ? parametros.get("descricao") : "Sem Descrição");
mailing.setIcAtivo("Sim");
mailing.setMailingTemplate(mailingTemplate);
ss.save(mailing);
while (iterator.hasNext())
{
CSVRecord registro = iterator.next();
String cpf = registro.get(mailingTemplate.getCampoUnicoIdentificador());
ContatoBean contato = mapaContatos.get(cpf);
if (contato == null)
{
contato = mailingFactory.buildContatoFromTemplate(registro, mailing);
contador++;
if (contador >= NUMERO_REGISTROS_GRAVAR)
{
contador = 0;
mapaContatos.clear();
ss.flush();
ss.clear();
}
}
mailingFactory.atualizarNumeroContato(registro, contato);
mapaContatos.put(cpf, contato);
ss.saveOrUpdate(contato);
}
ss.flush();
ss.clear();
ss.getTransaction().commit();
}
catch (Exception ex)
{
ss.getTransaction().rollback();
throw new SistemaException(ex);
}
finally
{
IOUtils.closeQuietly(inputStreamReader);
IOUtils.closeQuietly(stream);
mapaContatos.clear();
}
这是解析csv文件并在数据库中保存一些记录的代码。
这是来自Profiler的一些屏幕抱歉链接,我不能发布图片由于在这里是新的:(
之前我强制使用GC
https://dl.dropboxusercontent.com/u/17155314/Before%20GC.png
之后我强制使用GC
https://dl.dropboxusercontent.com/u/17155314/After%20GC.png
正如您在图表中看到的,它开始分配内存并释放一些内存,但不是所有已分配的内存。
重要的是,它只是使用了200 MB的内存,不像应用程序在具有32 gb等内存的服务器上运行,问题是,我刚刚启动了应用程序,并在生产中进行了测试以收集数据导入数据的数量要多得多,并且由于没有释放内存而导致一些导入的内存不足。
任何提示?
我的Hibernate.cfg用于批量插入
<property name="hibernate.jdbc.batch_size">5000</property>
<property name="hibernate.order_inserts">true</property>
<property name="hibernate.order_updates">true</property>
<property name="hibernate.cache.use_query_cache">false</property>
我使用5000作为批量大小,因为数据的导入量类似于400k~2kk记录,如果设置较低值则需要很长时间来处理。
我在使用WildFly 8.1的Java EE应用程序中使用Hibernate和Mysql