了解Java中用于容器管理的对象的垃圾收集

Gee*_*eek 4 java jsf garbage-collection

比方说,我有一个名为托管bean A@RequestScoped假设A有另一个管理bean的引用BB被宣布为@SessionScoped.A引用另一个具有更长范围的bean 的事实是否会阻止A在结束时收集垃圾HttpRequest

情况是否会改变另一种方式,即如果B包含对A?的引用?如果是,那么为什么?

Bal*_*usC 6

A引用另一个具有更长范围的bean 的事实是否会阻止A在结束时收集垃圾HttpRequest

不,如果没有对它的引用,则对象实例仅适用于GC.

默认情况下,请求范围bean仅在当前HTTP请求中引用(作为请求属性).因此,如果HTTP请求完成并被销毁,那么请求范围的bean将被完全取消引用,因此符合GC的条件.请求范围bean依次包含对会话范围bean的引用,这与GC完全无关.只有当会话范围bean没有在任何地方被引用时(例如,当会话已经过期时),那么会话范围的bean反过来也变得对于GC来说是可用的.


如果B包含对A的引用,情况是否会改变另一种方式?如果是,那么为什么?

是的,它会改变.默认情况下,会话范围bean仅在HTTP会话中引用(作为会话属性),其寿命比HTTP请求长.因此,只要建立了HTTP会话,请求范围的bean就会存在.这将导致潜在的数据完整性问题,因为您引用的东西应该不应该存在那么久.这就是为什么JSF不允许你在更广泛的范围内的bean中注入更窄的范围bean的原因之一@ManagedProperty.

总而言之,不应根据GC行为选择托管bean作用域,而应基于它所拥有的数据.另请参见如何选择正确的bean范围?