我们在具有内存限制的半嵌入式设备上部署应用程序。我们正在分析应用程序的堆转储并攻击最大的消费者。
我们将Spring 2.5与Spring DM 1.1一起使用,我们注意到一些具有更复杂的Spring上下文的bundle正在耗尽相当多的内存,因为Spring似乎保留了包含所有被解析的BeanDefinitions的整个对象图。来自XML。我认为,一旦应用程序初始化并注入了所有内容,大部分内容都是不必要的。
Spring是否有配置选项可以控制此行为?在某种低内存模式下运行?扔掉所有不必要的东西?交易计算时间的大小?
答案 0 :(得分:5)
我让团队成员对此有了更深入的了解并得到了一些有趣的结果。 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的配置的编程镜像)在初始化后被丢弃。
答案 1 :(得分:1)
您可以使用BeanFactory保存某些内存 - 请参阅3.8.1. BeanFactory or ApplicationContext:
由于ApplicationContext包含BeanFactory的所有功能,因此通常建议优先使用BeanFactory,除了一些有限的情况,例如在Applet中,内存消耗可能很关键,而且还有一些额外的千字节可能会有所作为。
答案 2 :(得分:0)
我不知道有什么办法让Spring在“轻”模式下运行。您可以尝试实现BeanFactoryPostProcessor并使用它从上下文中删除某些bean。我不知道这是否会导致内部Spring错误。
答案 3 :(得分:0)
如果你只在启动时使用Spring,即所有bean都是有线的,那么你不需要应用程序上下文或关闭逻辑,你可以启动你的应用程序然后清除对应用程序上下文的所有引用。
答案 4 :(得分:0)
如果您的Spring配置使用AOP和加载时间编织,您可以使用aop.xml通过使用1.6.5中引入的AspectJ类型降级功能从AspectJ重新获得一些内存。
<weaver options="-Xset:typeDemotion=true"/>
分析你的堆,如果找到很多RefType对象,上面的技巧会有所帮助。