memory - Spring webflow 使用大量内存

标签 memory out-of-memory spring-webflow

我们的 Webflow (2.3.1) 应用程序为我们通过浏览器打开的每个新流申请了大量内存。

下面的屏幕截图显示了我们的应用程序的内存使用情况。当应用程序启动时,它需要一个初始的 400 Mb。之后,我们在浏览器中打开 4 个单独的、相同的 Webflow 测试页面,每个页面都声称有大约 90Mb 的额外内存。

enter image description here

每个测试页面都从其自己的简单流程定义开始:

<?xml version="1.0" encoding="UTF-8"?>
<flow xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xmlns="http://www.springframework.org/schema/webflow"
      xsi:schemaLocation="http://www.springframework.org/schema/webflow
                                  http://www.springframework.org/schema/webflow/spring-webflow-2.0.xsd" start-state="start"> 
    <view-state id="start" view="test/test1">
    </view-state>
    <end-state id="end"/>
    <bean-import resource="../flow-beans.xml"/>
</flow>

JSP测试页面也很简单,只有一行文字。

当我们当前将 JVM 内存设置为 1.5Gb 时,应用程序最终会在打开大约 15 个不同的流后在服务器上崩溃并出现 OutOfMemoryExceptions。考虑到我们屏幕的低复杂性,1.5 Gb 似乎有点多。

我们想知道 Webflow 似乎为这些简单流/页面要求的内存量是否符合预期,因此我们是否应该为服务器 JVM 分配更多内存。如果没有,我们想知道如何减少这种内存使用。

下面是我们整个 webflow 配置。

我们已经尝试添加一个 flow-execution-repository 标签并尝试使用 max-executions-snapshots 和 max-executions 值,但即使是最保守的设置也不会改变我们看到的内存使用情况。

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:webflow="http://www.springframework.org/schema/webflow-config"
    xmlns:tx="http://www.springframework.org/schema/tx"
    xsi:schemaLocation="
       http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
       http://www.springframework.org/schema/webflow-config
       http://www.springframework.org/schema/webflow-config/spring-webflow-config-2.3.xsd
       http://www.springframework.org/schema/tx 
       http://www.springframework.org/schema/tx/spring-tx-3.0.xsd">

    <!-- Launches new flow executions and resumes existing executions. -->

    <webflow:flow-executor id="flowExecutor" flow-registry="flowRegistry">
    </webflow:flow-executor>

    <bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
        <property name="location" value="classpath:our.properties" />
        <property name="placeholderPrefix" value="$xxxx"></property>
    </bean>

    <tx:annotation-driven transaction-manager="$xxxx{txManager}" />

    <!-- Creates the registry of flow definitions for this application -->
    <webflow:flow-registry id="flowRegistry" flow-builder-services="flowBuilderServices">
        <webflow:flow-location-pattern value="classpath:flows/**/*-flow.xml" />
    </webflow:flow-registry>

    <bean id="viewFactoryCreator" class="org.springframework.webflow.mvc.builder.MvcViewFactoryCreator">
        <property name="viewResolvers" ref="viewResolver" />
    </bean>

    <bean id="expressionParser" class="org.springframework.expression.spel.standard.SpelExpressionParser">
        <constructor-arg name="configuration">
          <bean class="org.springframework.expression.spel.SpelParserConfiguration">
            <constructor-arg name="autoGrowCollections" value="true" />
            <constructor-arg name="autoGrowNullReferences" value="false" />
          </bean>
        </constructor-arg>
    </bean>

    <bean id="webflowExpressionParser" class="org.springframework.webflow.expression.spel.WebFlowSpringELExpressionParser">
        <constructor-arg name="expressionParser" ref="expressionParser" />
    </bean>

    <webflow:flow-builder-services id="flowBuilderServices" view-factory-creator="viewFactoryCreator" validator="validator" expression-parser="webflowExpressionParser"/>

    <bean id="validator" class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean" />


    <bean id="projectVersion" class="our.company.versions.ProjectVersionUtil">
        <property name="xxxxVersion" value="$xxxx{xxxx.version}" />
        <property name="systemConfigurationDao">    
            <ref bean="SystemConfigurationDao"/>
        </property>
    </bean>

</beans>

最佳答案

当 Spring Web Flow 开始一个新的流程时,它基本上会构造一个新的 BeanFactory 来加载 xml 文件并导入任何其他 xml 文件。新构造的 BeanFactoryDispatcherServlet 的上下文作为其父级。

现在的问题是 bean 工厂构造了所有 bean 的实例,甚至是那些在导入的 XML 文件中定义的实例。

<bean-import resource="../flow-beans.xml"/>

如果那里有很多 bean,那么每个流实例都会复制这些 bean。通常,您不希望所有 bean 都被复制并存储在用户 session 中。

flow-beans.xml 中删除单例 bean 并将它们放在正常的应用程序上下文中,它们仍然可以从流定义中引用。或者您可以简单地将 flow-beans.xml 添加到应用程序启动时加载的文件列表中。

关于memory - Spring webflow 使用大量内存,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25741579/

相关文章:

spring-webflow - 如何获取 FlowScope 中的变量?

linux - 将光盘 (HD) 路径加载到内存 (Minix)

c# - 重构 - System.OutOfMemoryException

.net - 处理大文件时正则表达式匹配中的 OutOfMemoryException

android - 在解码位图时捕获 OutOfMemoryError

java - c :foreach using List: Must evaluate to a Collection, 映射、数组或 null

java - Spring webflow URI 映射到包含斜杠 ("/"的流 ID

c# - 强制执行内存级别转换

(u/i)int_fastN_t 需要澄清

闭包词法环境中的 JavaScript 内存泄漏