В Glassfish создается лишний SFSB, что приводит к утечке памяти - PullRequest
2 голосов
/ 27 марта 2012

Я пытаюсь внедрить один SFSB в базовый компонент ViewScoped JSF в Glassfish 3.1.1.

Мой журнал показывает это, то есть, что создается ДВА SFSB, хотя только второй получает инъекцию:

INFO: constructed a new sfsb: com.example.test.service.impl._TestSFSBImpl_Serializable@f48cde0
INFO: constructed a new sfsb: com.exmaple.test.service.impl._TestSFSBImpl_Serializable@13dbf5ce
INFO: constructed a new view scoped bean: com.example.test.ui.TestViewScopedSFSB@4de6b191

Позже, когда я ухожу и бин ViewScoped выходит из области видимости, я вызываю remove () на SFSB, и я вижу это в журнале:

INFO: destroying view scoped bean: com.example.test.ui.TestViewScopedSFSB@4de6b191
INFO: removing sfsb: com.example.test.service.impl._TestSFSBImpl_Serializable@13dbf5ce
INFO: destroying sfsb: com.example.test.service.impl._TestSFSBImpl_Serializable@13dbf5ce

Но лишний первый конец, заканчивающийся на @ f48cde0, никогда не вводился, поэтому у меня нет к нему дескриптора, и он никогда не удаляется.Только позже, когда я выключаю сервер, я вижу, что он удален.

Вот мой код:

Базовый компонент:

package com.example.test.ui;

import java.io.Serializable;
import java.util.logging.Logger;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import javax.ejb.EJB;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;
import javax.faces.event.AjaxBehaviorEvent;

import com.example.test.service.api.TestSFSB;

@ManagedBean(name = "testViewScopedSFSB")
@ViewScoped
public class TestViewScopedSFSB implements Serializable {

  private static final long serialVersionUID = 1L;
  private static final Logger LOGGER = Logger.getLogger(TestViewScopedSFSB.class.getCanonicalName());

  @EJB
  private TestSFSB testSFSB;

  @PostConstruct
  public void postConstruct() {
    LOGGER.info("constructed a new view scoped bean: " + this);
  }

  public int getNumClicks() {
    return testSFSB.getNumClicks();
  }

  public void clicked(AjaxBehaviorEvent event) {
    testSFSB.clicked();
  }

  @PreDestroy
  public void preDestroy() {
    LOGGER.info("destroying view scoped bean: " + this);
    testSFSB.remove();
  }

}

Интерфейс SFSB:

package com.example.test.service.api;

public interface TestSFSB {

  void clicked();

  int getNumClicks();

  void remove();

}

Реализация SFSB:

package com.example.test.service.impl;

import java.util.logging.Logger;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import javax.ejb.Local;
import javax.ejb.Remove;
import javax.ejb.Stateful;

import com.example.test.service.api.TestSFSB;

@Stateful
@Local(TestSFSB.class)
public class TestSFSBImpl implements TestSFSB {

  private static final long serialVersionUID = 1L;
  private static final Logger LOGGER = Logger.getLogger(TestSFSBImpl.class.getCanonicalName());

  int numClicks = 0;

  @PostConstruct
  public void postConstruct() {
    LOGGER.info("constructed a new sfsb: " + this);
  }

  @Override
  public void clicked() {
    numClicks++;
  }

  @Override
  public int getNumClicks() {
    return numClicks;
  }

  @Override
  @Remove
  public void remove() {
    LOGGER.info("removing sfsb: " + this);
  }

  @PreDestroy
  public void preDestroy() {
    LOGGER.info("destroying sfsb: " + this);
  }

}

И, наконец, страница jsf:

<?xml version="1.0" encoding="ISO-8859-1" ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<h:html xmlns="http://www.w3.org/1999/xhtml"
    xmlns:c="http://java.sun.com/jsp/jstl/core"
    xmlns:f="http://java.sun.com/jsf/core"
    xmlns:h="http://java.sun.com/jsf/html"
    xmlns:ui="http://java.sun.com/jsf/facelets">

<h:head>

</h:head>

<h:body>
    <h:form>
        <h:commandLink action="/public/publicResource.jsf" value="Home" />
        <h:panelGrid id="panel1">
            <h:commandButton value="Click me">
                <f:ajax event="click" listener="#{testViewScopedSFSB.clicked}"
                    render="panel1" />
            </h:commandButton>
            <h:outputText value="#{testViewScopedSFSB.numClicks}" />
        </h:panelGrid>
    </h:form>

</h:body>
</h:html>

Это такая простая настройка ... какого чертаэто может быть?Возможно, ошибка в Glassfish?

РЕДАКТИРОВАТЬ: Для того, чтобы развеять любые "сомнения" в достоверности того, о чем я сообщаю, вот журнал, когда я загружаю страницу 10 раз.Обратите внимание, 20 SFSB создано, 2 каждый раз, но только 1 очищен, когда я ухожу.

INFO: constructed a new sfsb: com.example.test.service.impl._TestSFSBImpl_Serializable@561b0019
INFO: constructed a new sfsb: com.example.test.service.impl._TestSFSBImpl_Serializable@2767c7d9
INFO: constructed a new view scoped bean: com.example.test.ui.TestViewScopedSFSB@7b239469
INFO: destroying view scoped bean: com.example.test.ui.TestViewScopedSFSB@7b239469
INFO: removing sfsb: com.example.test.service.impl._TestSFSBImpl_Serializable@2767c7d9
INFO: destroying sfsb: com.example.test.service.impl._TestSFSBImpl_Serializable@2767c7d9

INFO: constructed a new sfsb: com.example.test.service.impl._TestSFSBImpl_Serializable@5c8608b9
INFO: constructed a new sfsb: com.example.test.service.impl._TestSFSBImpl_Serializable@63a6d923
INFO: constructed a new view scoped bean: com.example.test.ui.TestViewScopedSFSB@5ef9bbf1
INFO: destroying view scoped bean: com.example.test.ui.TestViewScopedSFSB@5ef9bbf1
INFO: removing sfsb: com.example.test.service.impl._TestSFSBImpl_Serializable@63a6d923
INFO: destroying sfsb: com.example.test.service.impl._TestSFSBImpl_Serializable@63a6d923

INFO: constructed a new sfsb: com.example.test.service.impl._TestSFSBImpl_Serializable@31a4ef37
INFO: constructed a new sfsb: com.example.test.service.impl._TestSFSBImpl_Serializable@43551d57
INFO: constructed a new view scoped bean: com.example.test.ui.TestViewScopedSFSB@8f95d4a
INFO: destroying view scoped bean: com.example.test.ui.TestViewScopedSFSB@8f95d4a
INFO: removing sfsb: com.example.test.service.impl._TestSFSBImpl_Serializable@43551d57
INFO: destroying sfsb: com.example.test.service.impl._TestSFSBImpl_Serializable@43551d57

INFO: constructed a new sfsb: com.example.test.service.impl._TestSFSBImpl_Serializable@69e3f60e
INFO: constructed a new sfsb: com.example.test.service.impl._TestSFSBImpl_Serializable@5f91e550
INFO: constructed a new view scoped bean: com.example.test.ui.TestViewScopedSFSB@63661834
INFO: destroying view scoped bean: com.example.test.ui.TestViewScopedSFSB@63661834
INFO: removing sfsb: com.example.test.service.impl._TestSFSBImpl_Serializable@5f91e550
INFO: destroying sfsb: com.example.test.service.impl._TestSFSBImpl_Serializable@5f91e550

INFO: constructed a new sfsb: com.example.test.service.impl._TestSFSBImpl_Serializable@266c4c10
INFO: constructed a new sfsb: com.example.test.service.impl._TestSFSBImpl_Serializable@ff5c225
INFO: constructed a new view scoped bean: com.example.test.ui.TestViewScopedSFSB@4f9d1352
INFO: destroying view scoped bean: com.example.test.ui.TestViewScopedSFSB@4f9d1352
INFO: removing sfsb: com.example.test.service.impl._TestSFSBImpl_Serializable@ff5c225
INFO: destroying sfsb: com.example.test.service.impl._TestSFSBImpl_Serializable@ff5c225

INFO: constructed a new sfsb: com.example.test.service.impl._TestSFSBImpl_Serializable@42650c3b
INFO: constructed a new sfsb: com.example.test.service.impl._TestSFSBImpl_Serializable@7806178a
INFO: constructed a new view scoped bean: com.example.test.ui.TestViewScopedSFSB@57f3a295
INFO: destroying view scoped bean: com.example.test.ui.TestViewScopedSFSB@57f3a295
INFO: removing sfsb: com.example.test.service.impl._TestSFSBImpl_Serializable@7806178a
INFO: destroying sfsb: com.example.test.service.impl._TestSFSBImpl_Serializable@7806178a

INFO: constructed a new sfsb: com.example.test.service.impl._TestSFSBImpl_Serializable@70879d38
INFO: constructed a new sfsb: com.example.test.service.impl._TestSFSBImpl_Serializable@5763013f
INFO: constructed a new view scoped bean: com.example.test.ui.TestViewScopedSFSB@24e6fbeb
INFO: destroying view scoped bean: com.example.test.ui.TestViewScopedSFSB@24e6fbeb
INFO: removing sfsb: com.example.test.service.impl._TestSFSBImpl_Serializable@5763013f
INFO: destroying sfsb: com.example.test.service.impl._TestSFSBImpl_Serializable@5763013f

INFO: constructed a new sfsb: com.example.test.service.impl._TestSFSBImpl_Serializable@49649260
INFO: constructed a new sfsb: com.example.test.service.impl._TestSFSBImpl_Serializable@552ee43b
INFO: constructed a new view scoped bean: com.example.test.ui.TestViewScopedSFSB@798a092d
INFO: destroying view scoped bean: com.example.test.ui.TestViewScopedSFSB@798a092d
INFO: removing sfsb: com.example.test.service.impl._TestSFSBImpl_Serializable@552ee43b
INFO: destroying sfsb: com.example.test.service.impl._TestSFSBImpl_Serializable@552ee43b

INFO: constructed a new sfsb: com.example.test.service.impl._TestSFSBImpl_Serializable@1a722605
INFO: constructed a new sfsb: com.example.test.service.impl._TestSFSBImpl_Serializable@3c1e1fd3
INFO: constructed a new view scoped bean: com.example.test.ui.TestViewScopedSFSB@5dbb747a
INFO: destroying view scoped bean: com.example.test.ui.TestViewScopedSFSB@5dbb747a
INFO: removing sfsb: com.example.test.service.impl._TestSFSBImpl_Serializable@3c1e1fd3
INFO: destroying sfsb: com.example.test.service.impl._TestSFSBImpl_Serializable@3c1e1fd3

INFO: constructed a new sfsb: com.example.test.service.impl._TestSFSBImpl_Serializable@21da38c0
INFO: constructed a new sfsb: com.example.test.service.impl._TestSFSBImpl_Serializable@7dc3d69c
INFO: constructed a new view scoped bean: com.example.test.ui.TestViewScopedSFSB@443edc45
INFO: destroying view scoped bean: com.example.test.ui.TestViewScopedSFSB@443edc45
INFO: removing sfsb: com.example.test.service.impl._TestSFSBImpl_Serializable@7dc3d69c
INFO: destroying sfsb: com.example.test.service.impl._TestSFSBImpl_Serializable@7dc3d69c

И, наконец, когда я выгружаю приложение, обратите внимание, что 10 лишних SFSB окончательно уничтожаются:

INFO: destroying sfsb: com.example.test.service.impl._TestSFSBImpl_Serializable@561b0019
INFO: destroying sfsb: com.example.test.service.impl._TestSFSBImpl_Serializable@5c8608b9
INFO: destroying sfsb: com.example.test.service.impl._TestSFSBImpl_Serializable@31a4ef37
INFO: destroying sfsb: com.example.test.service.impl._TestSFSBImpl_Serializable@69e3f60e
INFO: destroying sfsb: com.example.test.service.impl._TestSFSBImpl_Serializable@266c4c10
INFO: destroying sfsb: com.example.test.service.impl._TestSFSBImpl_Serializable@42650c3b
INFO: destroying sfsb: com.example.test.service.impl._TestSFSBImpl_Serializable@70879d38
INFO: destroying sfsb: com.example.test.service.impl._TestSFSBImpl_Serializable@49649260
INFO: destroying sfsb: com.example.test.service.impl._TestSFSBImpl_Serializable@1a722605
INFO: destroying sfsb: com.example.test.service.impl._TestSFSBImpl_Serializable@21da38c0

Поверьте мне на слово, исходя из моей репутации, что поведение соответствуетза 100 попаданий, вызывающих 200 бобов по одной схеме.

1 Ответ

0 голосов
/ 27 марта 2012

Это не ошибка, это особенность.И важный.В Java EE контейнер создает несколько экземпляров различных вещей (таких как bean-компоненты без сохранения состояния, bean-объекты, управляемые сообщениями, сущности и sfsbs), а также объединяет их в пулы и блокирует их, а что нет.Разрешение контейнеру делать и обрабатывать это - одна из причин использования Java EE.Вы можете настроить это поведение в большинстве контейнеров.

Из документации Glassfish:

Кроме того, сервер GlassFish поддерживает ряд настраиваемых параметров, которые могут управлять числом «с состоянием»экземпляры (сессионные компоненты с сохранением состояния и компоненты) и время их кэширования.

[..]

Один из наиболее важных параметров для сервера GlassFishОбъединение устойчиво-размера бассейна.Когда для постоянного размера пула задано значение больше 0, контейнер не только предварительно заполняет пул компонентов указанным числом компонентов, но также пытается обеспечить постоянное наличие этого количества компонентов в свободном пуле.Это гарантирует, что в состоянии готовности к обработке достаточно компонентов для обработки пользовательских запросов.

(http://docs.oracle.com/cd/E18930_01/html/821-2418/beahn.html#beahq)

Если вы этого не хотитеповедение, вы можете настроить его: читать и переходить по соответствующим ссылкам по ссылке выше.

...