Pergunta

Estamos implantando um aplicativo em um dispositivo semi-incorporado que tem restrições de memória. Olhando para poupar tudo o que podemos estamos analisando heap dumps do aplicativo e atacando os maiores consumidores.

Nós usamos Spring 2.5 em conjunto com a Primavera DM 1.1 e notamos que alguns dos nossos pacotes com contextos Primavera mais complexas estão usando-se um pouco de memória desde a Primavera parece manter ao redor do gráfico de objeto inteiro contendo todos os BeanDefinitions que foram analisados a partir do XML. Eu diria que a maior parte isso é desnecessário uma vez que o aplicativo foi inicializado e tudo é injetado.

Existem opções de configuração para a Primavera que permitem controlar este comportamento? Executar em algum modo de baixa memória? Jogue fora todas as coisas desnecessárias? Trade tempo de computação para o tamanho?

Foi útil?

Solução

Eu tive membros da equipe têm um olhar mais profundo para isso e tive alguns resultados interessantes. Primavera em sua configuração padrão muito não está interessado em ser especialmente conservador em seu uso de memória. Há 2 aspectos básicos que podem ser otimizadas para ganhos significativos:

  • O primeiro é uma propriedade não-expostos dentro do OsgiBundleXmlApplicationContext Primavera que você pode substituir se você estender a partir dessa classe e substituir o método customizeBeanFactory.

Nós fizemos assim:

@Override
protected void customizeBeanFactory(DefaultListableBeanFactory beanFactory) {
    super.customizeBeanFactory(beanFactory);
    String cacheBeanMetadataSysProp = System.getProperty(CACHE_BEAN_METADATA, "true");
    if (cacheBeanMetadataSysProp != null
        && cacheBeanMetadataSysProp.equalsIgnoreCase("false")) {
        beanFactory.setCacheBeanMetadata(false);
    } else if (cacheBeanMetadataSysProp != null
        && cacheBeanMetadataSysProp.equalsIgnoreCase("true")) {
        beanFactory.setCacheBeanMetadata(true);
    }
}

A configuração da propriedade "setCacheBeanMetadata" para false faz com que o BeanDefinitions (basicamente o espelho programático da configuração baseada em XML) para ser descartado após a inicialização.

  • A segunda mudança - que atualmente temos um protótipo para - É um remendo para o código-fonte da Primavera para fazer a inicialização lenta de coleções. Acontece que muitos objetos mola interna que representam Feijão e todas as suas propriedades têm um monte de membros que são inicializados para HashMaps e outras coleções por padrão, mas muito raramente são preenchidos com dados. Alterar o framework Spring para inicializar estes preguiçosamente vai salvar outra quantidade significativa de memória, mas é uma mudança muito mais invasivo.

Outras dicas

Você pode salvar alguma memória com um BeanFactory - veja 3.8.1. BeanFactory ou ApplicationContext :

Como o ApplicationContext inclui todas as funcionalidades do BeanFactory, é geralmente recomendado que seja usado em preferência ao BeanFactory, exceto por algumas situações limitadas, como em um applet, onde o consumo de memória pode ser crítico e alguns kilobytes extras pode fazer a diferença.

Eu não estou ciente de qualquer maneira de fazer Primavera executar no modo "luz". Você poderia tentar implementar um BeanFactoryPostProcessor e usá-lo para remover certos grãos a partir do contexto. Eu não tenho idéia se isso vai levar a erros de mola interna no entanto.

Se você só pode usar Primavera na inicialização, ie todos os grãos estão ligados e, em seguida, você não precisa o contexto do aplicativo ou a lógica de desligamento, você pode começar seu aplicativo e em seguida, desmarque todas as referências ao contexto de aplicação.

Se a sua configuração do Spring usa AOP e carga tecelagem tempo, você poderia usar aop.xml para recuperar alguma memória de AspectJ usando o recurso de tipo rebaixamento AspectJ que foi introduzida no 1.6.5.

<weaver options="-Xset:typeDemotion=true"/>

Analise o seu montão, se você encontrar muitos objetos RefType, o truque acima vai ajudar.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top