別のマネージドBean への参照があり、であると宣言されているA
とし@RequestScoped
ましょう。より長いスコープを持つ別の Bean への参照があるという事実は、最後にガベージコレクションを取得することを防ぎますか?A
B
B
@SessionScoped
A
A
HttpRequest
B
への参照が含まれている場合、状況は逆になりA
ますか? はいの場合、なぜですか?
別のマネージドBean への参照があり、であると宣言されているA
とし@RequestScoped
ましょう。より長いスコープを持つ別の Bean への参照があるという事実は、最後にガベージコレクションを取得することを防ぎますか?A
B
B
@SessionScoped
A
A
HttpRequest
B
への参照が含まれている場合、状況は逆になりA
ますか? はいの場合、なぜですか?
A
より長いスコープを持つ別のBeanを参照しているという事実A
は、最後にガベージコレクションを取得することを防ぎHttpRequest
ますか?
いいえ、オブジェクトインスタンスは、それへの参照がなくなった場合にのみGCの対象となります。
リクエストスコープのBeanは、デフォルトでは現在のHTTPリクエストでのみ参照されます(リクエスト属性として)。したがって、HTTPリクエストが終了して破棄された場合、リクエストスコープのBeanは完全に逆参照され、GCの対象になります。リクエストスコープのBeanにセッションスコープのBeanへの参照が含まれていることは、GCとはまったく関係ありません。セッションスコープのBeanがどこにも参照されていない場合(たとえば、セッションの有効期限が切れている場合)にのみ、セッションスコープのBeanもGCで使用できるようになります。
状況は逆に変わりますか?つまり、BにAへの参照が含まれている場合はどうなりますか?はいの場合、なぜですか?
はい、変更されます。セッションスコープのBeanは、デフォルトではHTTPセッションでのみ参照され(セッション属性として)、HTTPリクエストよりも長く存続します。したがって、リクエストスコープのBeanは、確立されたHTTPセッションが存在する限り存続します。これは、おそらくそれほど長くは存続しないはずの何かを参照しているため、潜在的なデータ整合性の問題を引き起こします。これが、JSFがスコープの狭いBeanをスコープの広いBeanに注入することを許可しない理由の1つです@ManagedProperty
。
結局のところ、マネージドBeanスコープは、GCの動作に基づいて選択するのではなく、保持しているデータに基づいて選択する必要があります。適切なBeanスコープを選択する方法も参照してください。
No.GCは、オブジェクトを指しているライブ参照の数にのみ依存し、その逆には依存しません。JVMは、常に有効な一連の参照を維持します。このルート参照セットから到達できないものはすべてガベージコレクションの対象となります。したがって、オブジェクトがAであり、ライブである別のオブジェクトBを指している場合でも、メモリ内の他のオブジェクトがAを参照していない場合、Aは使用可能です。 GC用。
この場合、Aのスコープは単一のリクエストに制限されます。したがって、サーバーがそのリクエスト処理を完了すると、メモリリークがない限り、Aはgcで使用可能になります。Bはセッションスコープを持っているため、メモリに残ります。
この例では、次の状況が発生します。リクエストスコープはオブジェクトA、Aを参照し、セッションスコープはオブジェクトBを参照します。リクエストが終了すると、リクエストは削除されるため、オブジェクトAを参照するものはありません。ガベージコレクションが可能です。その後もセッションはオブジェクトBを参照し、収集できません。Java仕様によると:
オブジェクトがコードで到達できなくなると、オブジェクトはガベージコレクションの対象になります。
これは、オブジェクトに到達できない場合は単純であることを意味します。この場合、Aには到達できませんが、Bには到達できます。
いずれにせよ、ルートオブジェクトの1つからあなたのオブジェクトへの参照がある場合(Main()または他の静的/シングルトン/ Beanからアクセスする方法がある限り、それがどれほど深くなるかは関係ありません)GCによって収集されません