Dlaczego wygasły @ Fasola nie została zniszczona, dopóki sesja nie wygasa

Używam Mojarra 2.2.4 na GlassFish 4 z Java 7.

Jak rozumiem z odpowiedzi BalusC naJak i kiedy jest niszczona fasola @ViewScoped w JSF?, @ViewScoped bean powinien zostać zniszczony w trzech przypadkach:

Post-back z wynikiem niezerowymWygaśnięcie sesjiPrzekroczono maksymalną liczbę widoków logicznych w sesji

Moje ziarna są niszczone w pierwszych dwóch przypadkach, ale nie wtedy, gdy przekroczona zostanie maksymalna liczba widoków logicznych. Sprawdziłem, że fasola działawygasać po przekroczeniu maksimum (otrzymuję wyjątek ViewExpiredException), ale nadal nie sązniszczony dopóki sesja się nie skończy.

Ze względu na zużycie pamięci chciałbym, aby fasola została zniszczona w tym trzecim przypadku, zwłaszcza, że ​​nie można jej użyć po wygaśnięciu.

pytaniaDlaczego fasola nie ulega zniszczeniu, gdy wygasa?Czy to błąd lub oczekiwane zachowanie?Co byłoby czystym obejściem, aby upewnić się, że fasola zostanie zniszczona?Aktualizacja: OmniFaces ViewScoped adnotacja niszczy fasolę, gdy tylko wygasną.Minimalny przykład

Oto moja fasola:

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

i moje 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>

i część mojego pliku 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>

Jeśli odświeżę sandbox.xhtml 50 razy, otrzymam 50 kopiiINFO: Constructing SandboxController w dzienniku. Ziarna nie są niszczone, niezależnie od tego, ile razy odświeżam. VisualVM potwierdza, że ​​do fasoli nadal odwołuje się ViewMap UIViewRoot. W moim pełnowymiarowym komponencie bean, który utrzymuje niezły stan, szybko otrzymuję OutOfMemoryException.

Po ręcznym wygaśnięciu sesji otrzymuję 50 kopiiINFO: Destroying SandboxController.

Jeśli dodam przycisk przesyłania do sandbox.xhtml i załaduję go w 4 różnych zakładkach, spróbuj przesłać pierwszy, otrzymam ViewExpiredException, zgodnie z oczekiwaniami, ale fasola nadal nie jest zniszczona.

Zachowanie jest takie samo, jeśli zamiast tego użyję adnotacji javax.faces.bean.ManagedBean i javax.faces.view.ViewScoped. Jednak adnotacja OmniFaces org.omnifaces.cdi.ViewScoped działa poprawnie.

W celu wyjaśnienia...

Moje @ViewScoped beansą zniszczone podczas wygaśnięcia sesji, w przeciwieństwie do problemów opisanych w pokrewnych pytaniach, takich jakPołączone ziarna ViewScoped prowadzą do wycieków pamięci

jestemnie pytając, dlaczego każda fasola nie jest zniszczonanatychmiast przy kolejnym odświeżaniu, jak to zostało zadane tutaj:Metoda JSF 2.1 ViewScopedBean @PreDestroy nie jest wywoływana. Chcę wiedzieć, dlaczego nawet kiedy wygasają i nie są już użyteczne, nadal nie są niszczone, a zatem kontynuują konsumowanie pamięci.

questionAnswers(1)

yourAnswerToTheQuestion