8

注: 私は mojarra 2.1.20 とリッチフェイス 4.2.2 を使用しています。

ヒープダンプを分析したところ、EL 式がセッションの LRUMap に存在することに気付きました。誰もがそれを避けるためになぜ、何をすべきかを知っていますか?

私が抱えている問題は、次の行を含む複合コンポーネントに関連しています:

  <rich:select ... valueChangeListener="#{cc.listValuesChangeListener}"

バッキング Bean my.package.MultiComboSelection を使用します。明らかに、my.package.MultiComboSelection には、listValuesChangeListener という名前のメソッドが定義されています。

私が見る問題は、LRUMap に ContextualCompositeMethodExpression (上記の valueChangeListener の式の表現) が含まれており、この cc 属性が MultiComboSelection を参照していることです。MultiComboSelection は UINamingContainer を拡張し、親/子プロパティを持ち、コンポーネント ツリーへの参照を持ちます。

その結果、参照チェーンがあるため、16MB のメモリをガベージ コレクションできません。

session -> LRUMap -> ContextualCompositeMethodExpression -> MultiComboSelection -> 親および 16MB

問題は、なぜそれが起こっているのか、どのように修正または回避するのかということです。

Class Name                                                                                   | Shallow Heap | Retained Heap | Retained Heap
--------------------------------------------------------------------------------------------------------------------------------------------
my.package.MultiComboSelection @ 0x78dc2bd50                                                 |           96 |    16 466 272 |    16 466 272
|- component javax.faces.component.UIComponentBase$FacetsMap @ 0x78dbbbd58                   |           48 |           128 |              
|- parent javax.faces.component.UIPanel @ 0x78dbbbdd8                                        |           88 |           760 |              
|- cc com.sun.faces.facelets.el.ContextualCompositeMethodExpression @ 0x78dc2bce0            |           32 |    16 466 384 |              
|  |- [0] java.lang.Object[2] @ 0x78dc2bc90                                                  |           24 |    16 466 464 |              
|  |  '- [0] java.lang.Object[1] @ 0x78dc2bc78                                               |           24 |    16 466 488 |              
|  |     '- [0] java.lang.Object[5] @ 0x78dc2bc20                                            |           40 |    16 466 576 |              
|  |        '- [0] java.lang.Object[2] @ 0x78dc2bc08                                         |           24 |    16 466 600 |              
|  |           '- [0] java.lang.Object[4] @ 0x78dc2bbe8                                      |           32 |    16 466 632 |              
|  |              '- value java.util.HashMap$Entry @ 0x78dc2bb40                             |           32 |    16 466 800 |              
|  |                 '- [1579] java.util.HashMap$Entry[2048] @ 0x78dbf61b8                   |        8 208 |    33 552 536 |              
|  |                    '- table java.util.HashMap @ 0x78dbb6860                             |           48 |    33 552 584 |              
|  |                       '- [1] java.lang.Object[2] @ 0x78ad95340                          |           24 |    33 552 608 |              
|  |                          '- value java.util.LinkedHashMap$Entry @ 0x78ad952c0           |           40 |    33 552 736 |              
|  |                             |- after, before java.util.LinkedHashMap$Entry @ 0x78acbe6a0|           40 |            40 |              
|  |                             |- [0] java.util.HashMap$Entry[2] @ 0x78ad952a8             |           24 |            24 |              
|  |                             |  '- table com.sun.faces.util.LRUMap @ 0x78ad95270         |           56 |    33 552 856 |              
--------------------------------------------------------------------------------------------------------------------------------------------
4

3 に答える 3

6

問題 1462ContextualCompositeMethodExpression修正の結果として、 は複合コンポーネント全体をインスタンス変数として参照しています。このメモリ リークの問題について、1 人のユーザーがissue 1940として報告しています。その後、インスタンス変数は問題 1943の修正の結果としてマークされました。ただし、問題 1940 は何らかの理由で 1943 の重複としてマークされていました。2 人のユーザーが問題 1940 の下部にある問題について、メモリ リークの問題がまだ未解決であると正当にコメントしていますが、関連する新しい問題レポートは見られません。その後に。この問題は、複合コンポーネントに値変更リスナーなどのメソッド式が含まれている場合にのみ発生します。transient

理論的には、ビュー ステートへの参照を保持する代わりに、セッションでビュー ステートをシリアル化するように Mojarra に指示することで、この問題を回避できます。インスタンス変数がマークされtransientているため、バイパスされます。の次のコンテキスト パラメータによってそれを実現できますweb.xml

<context-param>
    <param-name>com.sun.faces.serializeServerState</param-name>
    <param-value>true</param-value>
</context-param>

繰り返しますが、理論的には。私はそれをテストしませんでした。

代わりに MyFaces を試してみることもできます。それで問題が解決するとは言えませんが、MyFaces 2.x は、状態管理、メモリ使用量、およびパフォーマンスに関して、Mojarra よりもはるかに慎重であることを知っています。

それまでの間、問題 1940、このスタック オーバーフローの質問、およびあなたの調査結果を参照して、Mojarra の新しい問題を作成することを強くお勧めします。ビューステートで UI コンポーネントを参照することは絶対に正しくありません。UI コンポーネント インスタンスは、ビュー スコープではなく、本質的にリクエスト スコープです。


更新: これは Mojarra 2.2.8で修正された問題 3198として再報告され、Mojarra 2.1.29 でバックポートされた問題 3544に従って再報告されました。したがって、少なくともこれらのバージョンにアップグレードすると、使用していないときcom.sun.faces.serializeServerState=true(またはjavax.faces.SERIALIZE_SERVER_STATE=trueJSF 2.2 ごと) にこのメモリ リークが修正されるはずです。

于 2013-10-11T10:22:12.303 に答える
2

を持つ複合要素で同様の問題がありましたactionListener。Composite-Element は の を収集しましたListDataObjects、それらは GarbageCollected である必要があります。list.clear()リストをリロードする前に、このメモリリークを防ぐのに役立つことがわかりました。

于 2013-12-16T15:22:26.367 に答える
1

これはおそらくMojarra のhttps://java.net/jira/browse/JAVASERVERFACES-3544で修正されています。

于 2015-09-01T13:16:01.273 に答える