2

问候,

我有丰富的面孔应用程序(3.3.2.SR1)。该应用程序使用 ModelPanel 来查看实体。在我想显示它们之前,所有模式面板都不会渲染(渲染 = false)。应用程序变得大,并且从一个面板到其他使用许多关系。一切正常,但如果组件渲染为真或假,richfaces 似乎会在所有可能的情况下在内存中创建 UIComponent 树。当我尝试检查应用程序的内存使用情况时(我使用 YourKit Java Profiler 来满足这些需求),我发现它在一个会话中使用了大量内存。

我将 Facelets 与 Richfaces 一起使用,我尝试使用

<c:if test="rendred condition"... /> content </c:if>

它开始使用显着减少的内存,但是......当我用面板重新渲染该区域时,父屏幕上的控件停止工作。我怀疑这是因为每次更改组件树时都会重新创建整个树,并且我有不同步的客户端(html)和服务器(面孔)部分。

有人可以建议我如何减少内存使用吗?我有真正的问题,因为 HeapMemory 中的 StandardSession 对象使用 60-150Mb。几乎所有这些内存都用于 UIControls。

问题示例:

我有引用 panel1、panel2、panel3 的页面。

面板是:

<rich:modalPanel >
    <a4j:outputPanel layout="block" 
             rendered="#{PanelBeanHolder.renderedViewScreen}">
        <ui:insert name="panelContent" />
    </a4j:outputPanel>
</rich:modalPanel>

我仅在执行此操作时才呈现面板。并且在我需要之前不想加载输出面板的 UI 控件。

先感谢您。

PS我尝试做以下来改善这种情况

在 web.xml中配置会话中的视图数量:

<context-param>
    <param-name>com.sun.faces.numberOfViewsInSession</param-name>
    <param-value>4</param-value>
</context-param>

<context-param>
    <param-name>com.sun.faces.numberOfLogicalViews</param-name>
    <param-value>4</param-value>
</context-param>

它必须改进 StateHolder 对象,但并没有太大帮助。当这些数字增长时,我进行了测量并且内存使用量也在增长。但是,当我厌倦将它们设置为 1,1 - 一些页面停止工作。有时请求被转发到欢迎页面。2,2 改善了这种情况,但转发到欢迎页面的问题仍然存在。

尝试在 javax.faces.STATE_SAVING_METHOD 中使用客户端模式。它仍然为 UIComponent 模型使用大量内存。即使对象被序列化并且必须存储在表单中。

尝试在 faces.config 中重写 stateManager:

<state-manager>org.ajax4jsf.application.CompressAjaxStateManager</state-manager>

并重写 buildViewState 和 restoreView 以压缩流。它没有多大帮助。

4

1 回答 1

3

JSF 使用在请求之间维护的有状态组件树。默认情况下,这通常在会话中维护。您可以使用一些功能来控制它。

配置状态保存参数

通常有特定于实现的参数来控制会话中存储的视图数量 - 根据您的应用程序的行为方式,这可能很容易获胜。

javax.faces.STATE_SAVING_METHOD您可以使用参数将状态保存在表单中。但是,请注意您在每个请求中发送更多信息,并且允许客户端指示服务器端状态存在安全风险(确保您对您的实现如何加密此数据感到满意)。您将需要检查与您的组件库(即 RichFaces)的兼容性,尤其是在您使用 AJAX 时。

JSF 2 使用一种新的状态保存机制来减少会话开销;您faces-config.xml将需要更新到 2.0 版本。我相信这个想法来自 Apache Trinidad,因此您可以从那里提取 JSF 2 之前的版本。

进行自己的状态保存和/或视图创建

实现您自己的StateManager和/或ViewHandler让您以编程方式控制视图的处理方式。例如,您可以将StateManager持久视图写入数据库(具有适当的超时和清理)。

使用组件绑定和瞬态控件

您可以对组件的创建方式进行编程控制。从绑定规范:

  • 当第一次创建组件实例时(通常通过UIComponentELTag在 JSP 页面中被 a 引用),JSF 实现将检索ValueExpression名称绑定,并调用getValue()它。如果此调用返回一个非空UIComponent值(因为 JavaBean 已经以编程方式实例化并配置了一个组件),那么该实例将被添加到正在创建的组件树中。如果调用返回 null,则将创建一个新的组件实例,将其添加到组件树中,并在组件树上setValue()调用ValueExpression(这将导致 JavaBean 上的属性设置为新创建的组件实例)。
  • 当在请求处理生命周期的恢复视图阶段重新创建组件树时,对于每个ValueExpression与名称“绑定”关联的组件,setValue()将在其上调用,并传递重新创建的组件实例。

您可能可以将其与子组件的瞬态属性一起使用,以编程方式控制子组件的创建/销毁。这是手动的,有点混乱,但在极端情况下可能会起作用。

我确信这不是一份详尽的清单。

于 2011-01-30T16:06:33.160 回答