¿Por qué los beans @ViewScoped caducados no se destruyen hasta que expira la sesión?

Estoy usando Mojarra 2.2.4 en GlassFish 4 con Java 7.

Como entiendo por la respuesta de BalusC a¿Cómo y cuándo se destruye un bean @ViewScoped en JSF?Los frijoles @ViewScoped deben ser destruidos en tres casos:

Post-back con resultado no nuloVencimiento de la sesiónNúmero máximo de vistas lógicas en sesión superadas

Mis beans se están destruyendo en los dos primeros casos, pero no cuando se excede el número máximo de vistas lógicas. He verificado que los frijoles lo hacen.expirar cuando se excede el máximo (obtengo una excepción ViewExpiredException), pero todavía no sedestruido Hasta que la sesión expire.

Por razones de consumo de memoria, me gustaría que los beans se destruyeran en este tercer caso, especialmente porque no se pueden utilizar después de la expiración.

Preguntas¿Por qué no se destruyen los frijoles cuando caducan?¿Es este un error o comportamiento esperado?¿Qué sería una solución alternativa limpia para asegurarse de que los frijoles se destruyan?Actualizar: OmniFaces ViewScoped anotación destruye los frijoles tan pronto como caducan.Ejemplo mínimo

Aquí está mi frijol:

@javax.inject.Named("sandboxController")
@javax.faces.view.ViewScoped
public class SandboxController implements Serializable {
    private static final Logger log = Logger.getLogger(SandboxController.class.getName());
    @PostConstruct
    public void postConstruct() {
        log.log(Level.INFO, "Constructing SandboxController");
    }
    @PreDestroy
    public void preDestroy() {
        log.log(Level.INFO, "Destroying SandboxController");
    }
    public String getData() {
        return "abcdefg";
    }
}

y mi sandbox.xhtml:

<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" 
      xmlns:h="http://xmlns.jcp.org/jsf/html">
    <body>
        <h:form>
            <h:outputText value="#{sandboxController.data}"/>
        </h:form>
    </body>
</html>

y parte de mi web.xml:

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

Si actualizo el sandbox.xhtml 50 veces, obtengo 50 copias deINFO: Constructing SandboxController en el registro Los frijoles no se destruyen, independientemente de cuántas veces se actualice. VisualVM confirma que los frijoles siguen siendo referenciados por ViewMap de UIViewRoot. En mi bean de tamaño completo, que mantiene un poco de estado, rápidamente obtengo una excepción OutMemoryException.

Cuando caduca manualmente la sesión, obtengo 50 copias deINFO: Destroying SandboxController.

Si agrego un botón de envío a sandbox.xhtml y lo cargo en 4 pestañas diferentes, luego intento enviar la primera, obtengo una ViewExpiredException, como se esperaba, pero el bean aún no está destruido.

El comportamiento es el mismo si en su lugar utilizo las anotaciones javax.faces.bean.ManagedBean y javax.faces.view.ViewScoped. Sin embargo, la anotación de OmniFaces org.omnifaces.cdi.ViewScoped funciona correctamente.

Para aclarar...

Mis frijoles @ViewScopedson se destruye al finalizar la sesión, a diferencia de los problemas descritos en preguntas relacionadas, comoLos frijoles ViewScoped vinculados conducen a fugas de memoria

yo soyno preguntando por qué no se destruye cada frijolinmediatamente en la actualización posterior como se cuestiona aquí:No se llama al método JSF 2.1 ViewScopedBean @PreDestroy. Quiero saber por qué es que incluso cuando caducan, y ya no son útiles, aún no se destruyen, y por lo tanto siguen consumiendo memoria.

Respuestas a la pregunta(1)

Su respuesta a la pregunta