Как я могу настроить Spring, чтобы сэкономить как можно больше памяти?

StackOverflow https://stackoverflow.com/questions/1049692

Вопрос

Мы развертываем приложение на полувстроенном устройстве с ограничениями по памяти.Стремясь спасти все, что можем, мы анализируем дампы кучи приложения и атакуем крупнейших потребителей.

Мы используем Spring 2.5 вместе со Spring DM 1.1 и замечаем, что некоторые из наших пакетов с более сложными контекстами Spring используют довольно много памяти, поскольку Spring, похоже, хранит весь граф объектов, содержащий все BeanDefinitions, которые были проанализированы из XML. .Я бы предположил, что большая часть этого не нужна, когда приложение инициализировано и все введено.

Существуют ли параметры конфигурации Spring, позволяющие контролировать такое поведение?Запустить в каком-нибудь режиме нехватки памяти?Выбросить все ненужное?Обменять время вычислений на размер?

Это было полезно?

Решение

Я попросил членов команды глубже изучить этот вопрос и получил некоторые интересные результаты.Spring в конфигурации по умолчанию совершенно не заинтересован в том, чтобы быть особенно консервативным в использовании памяти.Есть 2 основных аспекта, которые можно настроить для получения существенной выгоды:

  • Первое — это неоткрытое свойство внутри Spring. OsgiBundleXmlApplicationContext который вы можете переопределить, если вы расширите этот класс и переопределите customizeBeanFactory метод.

Мы сделали это так:

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

Установка свойства setCacheBeanMetadata в значение false вызывает BeanDefinitions (по сути, это программное зеркало вашей конфигурации на основе XML), которое будет удалено после инициализации.

  • Второе изменение, прототип которого у нас сейчас есть, — это патч для исходного кода Spring, позволяющий выполнять ленивую инициализацию коллекций.Оказывается, многие внутренние объекты Spring, представляющие Beans и все их свойства, имеют множество членов, которые по умолчанию инициализируются HashMaps и другими коллекциями, но очень редко заполняются данными.Изменение структуры Spring для их ленивой инициализации сэкономит еще один значительный объем памяти, но это гораздо более агрессивное изменение.

Другие советы

Вы можете сохранить некоторый память с помощью BeanFactory - см. 3.8.1.BeanFactory или ApplicationContext:

Поскольку ApplicationContext включает в себя все функциональные возможности BeanFactory, обычно рекомендуется использовать его вместо BeanFactory, за исключением нескольких ограниченных ситуаций, таких как в апплете, где потребление памяти может быть критическим, а несколько дополнительных килобайт могут оказаться неэффективными. разница.

Мне не известен какой-либо способ заставить Spring работать в «легком» режиме.Вы можете попробовать реализовать BeanFactoryPostProcessor и использовать его для удаления определенных bean-компонентов из контекста.Однако я понятия не имею, приведет ли это к внутренним ошибкам Spring.

Если вы используете Spring только при запуске, то есть все bean-компоненты подключены, и тогда вам не нужен контекст приложения или логика завершения работы, вы можете запустить свое приложение, а затем очистить все ссылки на контекст приложения.

Если ваша конфигурация Spring использует AOP и переплетение времени загрузки, вы можете использовать aop.xml, чтобы восстановить часть памяти из AspectJ, используя функцию понижения уровня типа AspectJ, которая была представлена ​​в 1.6.5.

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

Проанализируйте свою кучу, если вы обнаружите много объектов RefType, поможет приведенный выше трюк.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top