Tomcat 6 + Struts2 Memory leak

4 respostas
N

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,

4 Respostas

H

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?

N

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();
		}
	}
}
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();
		}
	}
}
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

D

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?


++²

H

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

Criado 20 de julho de 2012
Ultima resposta 20 de jul. de 2012
Respostas 4
Participantes 3