Zaczynamy eksperymentować z wdrażaniem naszych usług backendowych za pomocą CDI. Scenariusz jest następujący:Aplikacje i zakresy zależne CDI mogą konspirować, aby wpływać na wywóz śmieci?
EJB z @Startup jest uruchamiany po wdrożeniu EAR. ApplicationScoped fasola jest wstrzykiwany na to:
@ApplicationScoped
public class JobPlatform {
private PooledExecutor threadHolder;
@Inject @Any
private Instance<Worker> workerSource;
...
Fasola ma również metodę obserwatorem, który, gdy obserwuje zdarzenie, dostaje fasoli robotnik z instancji workerSource i kładzie go na puli wątków, gdzie ostatecznie prowadzi Do ukończenia.
Wszystko działa dobrze. Jednak ... zaczęliśmy widzieć problemy ze zbieraniem śmieci. Histogram sterty JMAP pokazuje, że wielu z tych pracowników kręci się wokół, a nie-śmieci gromadzone.
Uważamy, że jest to spowodowane połączeniem scoringu CDI. Strona API dla @Dependant (http://docs.jboss.org/cdi/api/1.0-SP1/javax/enterprise/context/Dependent.html) wzmacnia jaśniej co w docs:
- Instancja fasoli z zakresu @Dependent wtryskiwanego do pola, konstruktor fasoli lub metoda inicjująca jest zależny przedmiot komponent bean komponentu bean lub Java EE, do którego został on wstrzyknięty.
- Instancja komponentu bean o zasięgu @Dependent wprowadzona do metody producenta jest zależnym obiektem produkowanej instancji komponentu bean metody producenta.
- Instancja komponentu bean o zasięgu @Dependent uzyskana przez bezpośrednie wywołanie instancji jest zależnym obiektem wystąpienia instancji.
Więc po to:
- workerSource fasola jest zobowiązany do JobPlatform, a zatem ma żywotność ApplicationScoped
- Wszelkie fasola pracownik pobierane za pomocą tej instancji są zobowiązane do niego i dlatego istnieje okres trwałości ApplicationScoped:
- Ponieważ magazyn bean kontekstu ApplicationScoped (moja znajomość terminologii jest tu nieco mglisty) nadal ma wartość do fasoli pracownika, nie są niszczone/zebrane śmieci
Czy ktoś używający CDI zgadza się z tym? Czy doświadczyłeś tego braku zbierania śmieci, a jeśli tak, czy możesz zaproponować jakieś obejścia?
Pracownicy nie mogą być ApplicationScoped, ale platforma musi być. Gdybyśmy stworzyli niestandardowy WorkerScope (uh ohhh ...) i dodali adnotację do każdej klasy klasy robotniczej, czy to wystarczy, aby oddzielić zależność między źródłem roboczym a źródłem?
Są też pewne sugestie na temat Is it possible to destroy a CDI scope?, na które przyjrzę się, ale chciałem zrobić kopię zapasową, czy określenie zakresu wygląda jak uzasadniony powód.
Mam nadzieję, że możesz pomóc, dzięki.
Wielkie dzięki za tak szybkie odzyskanie - dobrze wiedzieć, że jest rozpoznawalny kwestia. Sprawi, że obejście problemu będzie już możliwe! Twoje zdrowie! –
Dla każdego, kto tu czyta, zauważ, że Weld 1.1 implementuje CDI 1.0, a nie CDI 1.1. –
Popraw Craig. Weld 2.0 implementuje CDI 1.1 (tak, wiem, że numeracja jest dziwna). Jeśli chcesz zobaczyć, jaki będzie CDI 1.1, wypróbuj Weld 2.0. Wierzę, że istnieją specjalne kompilacje JBoss AS7, które obejmują Weld 2.0. – LightGuard