Tomcat 6 + Struts2 Memory leak

Pessoal,

Alguém sabe se existe esse problema com o Struts 2 de memory leak?
Possuo uma aplicação em Struts 2, e a aplicação esta estourando 1gb de memoria dedicada para JVM, em teste locais.
Eu utilisei o Java Monitor para monitorar a aplicação e parece que conforme vai fazendo requisições a memoria só vai acumulando e não é liberada.

Alguem ja deparou com algo parecido? É alguma coisa no Struts 2? Alguma configuração? Qualquer opnião é bem vinda porque não sei mais o que fazer :stuck_out_tongue:

Att,

Já parou para pensar que pode ser erro de desenvolvimento?

Vocês estão jogando objetos dentro do httpSession? Vocês estão fechando toda transação aberta?

Existem 2 coisas que eu reparei que não sei se são boas praticas.

Um entityManagerFactory


public class EntityManagerFactoryCreator implements EntityManagerFactory {

	private EntityManagerFactory factory;


	public void create() {
		factory = Persistence.createEntityManagerFactory("default");
	}

	public void destroy() {
		System.out.println("destruindo!!!" + " " + factory.hashCode());
		factory.close();
	}

	public void close() {
		if(isOpen()){
			System.out.println("fechando!!!" + " " + factory.hashCode());
			factory.close();
		}
	}

	public EntityManager createEntityManager() {
		System.out.println("Ta aberta? " + isOpen() );
		
		if(isOpen()){
			System.out.println("Ja ta aberta!!!" + " " + factory.hashCode());
			
			return factory.createEntityManager();
		}else{
			create();
			System.out.println("criou!!!" + " " + factory.hashCode());
			return factory.createEntityManager();
		}
	}
}

[code]

public class CadUsuarioDAO implements GenericDAO<CadUsuario, Long> {

Logger log = Logger.getLogger(CadUsuarioDAO.class);

private EntityManager manager;
private EntityManagerFactoryCreator managerFactoryCreator;

public CadUsuarioDAO() {
	super();
	this.managerFactoryCreator = new EntityManagerFactoryCreator();
}

public void save(CadUsuario instance) throws DAOException {
	manager = managerFactoryCreator.createEntityManager();
	EntityTransaction transaction = manager.getTransaction();
	try {
		transaction.begin();
		manager.persist(instance);
		transaction.commit();
	} catch (Exception e) {
		log.error("Erro ", e);
		throw new DAOException(e);
	} finally {
		if (transaction != null && transaction.isActive()) {
			transaction.rollback();
		}
		manager.close();
	}
}

}[/code]
Eu vi que não cria uma EntityManager se ela ja esta aberta, porem eu não vejo em nenhum lugar ela fechando no DAO. Esse padrão é bom?

E tem outra coisa
Todos os atributos de uma Action são instanciados no construtor, isso cria um uso desnecessário de memória? Que denpendendo do medoto da action que é chamado o objeto não é utilizado.


@ParentPackage(value = "cadastro")
@Results({
		@Result(name = "success", type = "redirectAction", params = {
				"actionName", "usuario", "method", "listar" }),
		@Result(name = "cadastrar", type = "dispatcher", location = "usuario-cadastrar.jsp"),
		@Result(name = "alterar", type = "dispatcher", location = "usuario-alterar.jsp"),
		@Result(name = "input", type = "dispatcher", location = "usuario-cadastrar.jsp"),
		@Result(name = "listar", type = "dispatcher", location = "usuario-listar.jsp"),
		@Result(name = "listar-tabela", type = "dispatcher", location = "usuario-listar-tabela.jsp"),
		@Result(name = "usuario-grupos", type = "dispatcher", location = "usuario-grupos.jsp") })
@Namespace(value = "/cadastro")
public class UsuarioController extends ActionSupport implements SessionAware {

	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;

	private Logger log = Logger.getLogger(UsuarioController.class);

	private Long id;
	private String confirmaSenha;
	private String pesquisa;
	private CadUsuario usuario;
	private List<CadUsuario> usuarios;
	private List<CadUsuario> supervisores;
	private List<CadGrupo> grupos;
	private CadUsuarioDAO cadUsuarioDAO;
	private CadGrupoDAO cadGrupoDAO;
	private CadUsuarioGrupoDAO cadUsuarioGrupoDAO;
	private CadEmailDAO cadEmailDAO;

	private Map<String, Object> session;

	public UsuarioController() {
		super();
		usuarios = new ArrayList<CadUsuario>();
		supervisores = new ArrayList<CadUsuario>();
		grupos = new ArrayList<CadGrupo>();
		cadUsuarioDAO = new CadUsuarioDAO();
		cadGrupoDAO = new CadGrupoDAO();
		cadUsuarioGrupoDAO = new CadUsuarioGrupoDAO();
		cadEmailDAO = new CadEmailDAO();
	}

	public Long getId() {
		return id;
	}

	public void setId(Long id) {
		this.id = id;
	}

	public String getConfirmaSenha() {
		return confirmaSenha;
	}

	public void setConfirmaSenha(String confirmaSenha) {
		this.confirmaSenha = confirmaSenha;
	}
...

Alguma dessas coisas estariam influenciando em algo?

Agradeço a ajuda!

Abs

[quote=jakefrog]Já parou para pensar que pode ser erro de desenvolvimento?

Vocês estão jogando objetos dentro do httpSession? Vocês estão fechando toda transação aberta?[/quote]
++²

Você pode ir fazendo testes. comenta o código e veja se a memória continua oscilando.

Isso aqui eu também nunca vi e não faria: EntityManagerFactoryCreator implements EntityManagerFactory