Estou desesperado atrás de ajuda, pois na finalização da minha aplicação identifiquei um memory leak e não consigo resolvê-lo…
Vamos Lá… Utilizo Hibernate com JPA, e para servidor de aplicações o tomcat 6.0… As minhas consultas são feitas da seguinte forma:
EntityManagerFactory entityManagerFactory = Persistence
.createEntityManagerFactory(PERSISTENCE_UNIT);
EntityManager em = entityManagerFactory.createEntityManager();
StringBuffer queryString = new StringBuffer(" Select ind FROM Indicador ind ");
Query findAllQuery = em.createQuery(queryString.toString());
Collection<Object> indicadores = findAllQuery.getResultList();
if (indicadores != null){
logger.debug("** Found " + indicadores.size() + " records:");
}
return indicadores;
}[/code]
Então assim, eu compilo a aplicação ela roda numa boa, mas depois de um certo tempo, ela estoura o heap space com:
Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
at java.util.Arrays.copyOf(Unknown Source)
at java.lang.AbstractStringBuilder.expandCapacity(Unknown Source)
at java.lang.AbstractStringBuilder.append(Unknown Source)
at java.lang.StringBuffer.append(Unknown Source)
at org.hibernate.sql.SelectFragment.toFragmentString(SelectFragment.java:133)
at org.hibernate.persister.entity.AbstractEntityPersister.concretePropertySelectFragment(AbstractEntityPersister.java:1191)
at org.hibernate.persister.entity.AbstractEntityPersister.concretePropertySelectFragment(AbstractEntityPersister.java:1163)
at org.hibernate.persister.entity.AbstractEntityPersister.generateSnapshotSelectString(AbstractEntityPersister.java:1205)
at org.hibernate.persister.entity.AbstractEntityPersister.postConstruct(AbstractEntityPersister.java:2979)
at org.hibernate.persister.entity.SingleTableEntityPersister.<init>(SingleTableEntityPersister.java:431)
at org.hibernate.persister.PersisterFactory.createClassPersister(PersisterFactory.java:84)
at org.hibernate.impl.SessionFactoryImpl.<init>(SessionFactoryImpl.java:261)
at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1327)
at org.hibernate.cfg.AnnotationConfiguration.buildSessionFactory(AnnotationConfiguration.java:867)
at org.hibernate.ejb.Ejb3Configuration.buildEntityManagerFactory(Ejb3Configuration.java:669)
at org.hibernate.ejb.HibernatePersistence.createEntityManagerFactory(HibernatePersistence.java:126)
at javax.persistence.Persistence.createEntityManagerFactory(Persistence.java:52)
at javax.persistence.Persistence.createEntityManagerFactory(Persistence.java:34)
at com.Syge.database.ServIndicadores.carregarDados(ServIndicadores.java:302)
at principal.main.main(main.java:41)
Ja aumentei a memória da JVM, mas isso só prolonga o erro, o problema é como se a memoria fosse crescendo gradativamente e o Garbage Collector nunca coletasse os objetos inativos… Estou fazendo alguma coisa errado nas minhas consultas? Preciso de ajuda urgente, pois nem todo cliente tem condições de utilizar JVM com grande capacidade de memória… Preciso saber o que está causando esse memory leak, e o q esta consumindo a memória e não esta sendo removido do HEAP com o Garbage Collector
sim ali ta sem spring, mas eu o utilizo esse codigo e antigo
o problema esta nas consultas, quando realizo uma consulta a memoria permgen aumenta e nao abaixa mais,
parece q garda em cache
@Transactional(propagation = Propagation.REQUIRED)
private AbstractPersistentObject findById(AbstractPersistentObject entity) throws TNSException
{
long id = entity.getId();
String name = entity.getClass().getSimpleName();
entity = this.entityManager.find(entity.getClass(), entity.getId());
//this.entityManager.refresh(entity);
if (entity == null)
{
TNSException e = new TNSException();
e.setMensagemSimplificada(name + " com o ID: " + id + " não encontrado(a).");
e.setMensagemTecnica(name + " com o ID: " + id + " não encontrado(a).");
e.disparaExcecaoTratada();
}
this.entityManager.close();
name = null;
return entity;
}
[quote=rxavier][code] @Transactional(propagation = Propagation.REQUIRED)
private AbstractPersistentObject findById(AbstractPersistentObject entity) throws TNSException
{
long id = entity.getId();
String name = entity.getClass().getSimpleName();
entity = this.entityManager.find(entity.getClass(), entity.getId()); //this.entityManager.refresh(entity);
if (entity == null)
{
TNSException e = new TNSException();
e.setMensagemSimplificada(name + " com o ID: " + id + " não encontrado(a).");
e.setMensagemTecnica(name + " com o ID: " + id + " não encontrado(a).");
e.disparaExcecaoTratada();
}
this.entityManager.close();
name = null;
return entity;
}
[/code][/quote]
Uma dúvida, pq só nesse método vc faz close() do EM?