Por que os beans @ViewScoped expirados não são destruídos até que a sessão expire

Estou usando o Mojarra 2.2.4 no GlassFish 4 com Java 7.

Pelo que entendi da resposta da BalusC paraComo e quando um bean @ViewScoped é destruído no JSF?, Os beans @ViewScoped devem ser destruídos em três casos:

Post-back com resultado não nuloExpiração da sessãoNúmero máximo de visualizações lógicas na sessão excedido

Meus beans estão sendo destruídos nos dois primeiros casos, mas não quando o número máximo de visualizações lógicas é excedido. Eu verifiquei que os feijõesexpirar quando o máximo é excedido (recebo uma ViewExpiredException), mas eles ainda não sãodestruído até a própria sessão expirar.

Por razões de consumo de memória, eu gostaria que os beans fossem destruídos nesse terceiro caso, principalmente porque eles não são utilizáveis após a expiração.

QuestõesPor que os grãos não são destruídos quando expiram?Isso é um bug ou comportamento esperado?O que seria uma solução alternativa para garantir que os grãos sejam destruídos?Atualizar: Anotação do OmniFaces ViewScoped destrói os grãos assim que expiram.Exemplo Mínimo

Aqui está o meu feijão:

@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";
    }
}

e minha 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>

e parte do meu 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>

Se eu atualizar o sandbox.xhtml 50 vezes, recebo 50 cópias deINFO: Constructing SandboxController no log. Os grãos não são destruídos, independentemente de quantas vezes eu atualizo. O VisualVM confirma que os beans ainda são referenciados pelo ViewMap do UIViewRoot. No meu bean de tamanho normal, que mantém um bom estado, recebo rapidamente uma OutOfMemoryException.

Quando expiro manualmente a sessão, recebo 50 cópias deINFO: Destroying SandboxController.

Se eu adicionar um botão de envio ao sandbox.xhtml e carregá-lo em quatro guias diferentes, tente enviar a primeira, e recebo uma ViewExpiredException, conforme o esperado, mas o bean ainda não foi destruído.

O comportamento é o mesmo se eu usar as anotações javax.faces.bean.ManagedBean e javax.faces.view.ViewScoped. No entanto, a anotação do OmniFaces org.omnifaces.cdi.ViewScoped funciona corretamente.

Esclarecer...

Meus beans @ViewScopedestão sendo destruídos na expiração da sessão, diferentemente dos problemas descritos em perguntas relacionadas, comoOs beans com escopo definido levam a vazamentos de memória

eu sounão perguntando por que cada feijão não é destruídoimediatamente na atualização subsequente, conforme questionado aqui:O método JSF 2.1 ViewScopedBean @PreDestroy não é chamado. Quero saber por que, mesmo quando eles expiram e não são mais úteis, eles ainda não são destruídos e, portanto, continuam consumindo memória.

questionAnswers(1)

yourAnswerToTheQuestion