L'applicazione CDI e gli ambiti dipendenti possono cospirare per avere un impatto sulla raccolta dei rifiuti?

StackOverflow https://stackoverflow.com/questions/8385190

Domanda

Stiamo iniziando a sperimentare l'implementazione dei nostri servizi di backend utilizzando CDI. Lo scenario è questo:

EJB con @startup viene avviato quando l'orecchio viene distribuito. Un fagiolo copicato viene iniettato su questo:

@ApplicationScoped
public class JobPlatform {

    private PooledExecutor threadHolder;

    @Inject @Any
    private Instance<Worker> workerSource;
...

Il fagiolo ha anche un metodo Observer, che, quando si osserva un evento, ottiene un fagiolo dei lavoratori dall'istanza dei lavoratori e lo mette sul threadpool, dove alla fine corre al completamento.

Tutti lavorano bene. Tuttavia ... abbiamo iniziato a vedere problemi di raccolta dei rifiuti. Un istogramma di heap JMAP mostra che ci sono molti di questi lavoratori in giro, raccolti non-garbage.

Crediamo che ciò dipenda dalla combinazione di Scoping CDI. La pagina API per @dipendant (http://docs.jboss.org/cdi/api/1.0-Sp1/javax/enterprise/context/dipendent.html) rafforza più chiaramente ciò che è nei documenti:

  • Un'istanza di un fagiolo con portata @dipendente iniettata in un campo, il costruttore di fagioli o il metodo di inizializzatore è un oggetto dipendente del fagiolo o dell'istanza della classe dei componenti di java ee in cui è stato iniettato.
  • Un'istanza di un fagiolo con portata @dipendente iniettata in un metodo produttore è un oggetto dipendente dell'istanza del metodo del produttore che viene prodotto.
  • Un'istanza di un fagiolo con portata @dipendente ottenuta mediante invocazione diretta di un'istanza è un oggetto dipendente dell'istanza di istanza.

Quindi, seguendo questo:

  • Il bean workersource è vincolato alla piattaforma e quindi ha una durata delle applicazioni
  • Qualsiasi fagiolo di lavoratore recuperato utilizzando tale istanza è vincolato ad essa e quindi hanno una durata delle applicazioni
  • Poiché il fagiolo del contesto di applicazioni (la mia conoscenza della terminologia diventa un po 'confusa qui) ha ancora un riferimento ai fagioli dei lavoratori, non sono distrutti/immondizia raccolta

Qualcuno che usa CDI è d'accordo con questo? Hai sperimentato questa mancanza di garbage collection e, in tal caso, puoi suggerire delle soluzioni alternative?

I lavoratori non possono essere applicati, tuttavia la piattaforma deve essere. Se dovessimo creare un Custom WorkerCope (uh ohhh ...) e annotare ogni classe di lavoratori con esso, sarebbe sufficiente per separare la dipendenza tra lavoratore e fonte di istanza?

Ci sono anche alcuni suggerimenti a È possibile distruggere un ambito CDI? Che guarderò, ma volevo un backup sul fatto che lo scoping sembrasse un motivo valido.

Spero che tu possa aiutare, grazie.

È stato utile?

Soluzione

La tua comprensione è corretta. Questa è stata una svista nelle specifiche e qualcosa che sarà fissato in CDI 1.1. Instance Può avere una perdita di memoria proprio come hai descritto quando usato in un ambito di lunga durata come SessionScoped o ApplicationScoped. Quello che dovrai fare è ottenere una presa del Contextual o Bean per caso e distruggerlo in questo modo.

Per quello che stai facendo e per evitare la perdita di memoria, è meglio utilizzare i metodi BeanManager per creare istanze (in questo modo avrai anche una maniglia sul Bean e può distruggerlo) invece di Instance.

Altri suggerimenti

Durante la ricerca nell'implementazione della soluzione consigliata di Jason, ho trovato altre risorse relative al problema:

Il problema: https://issues.jboss.org/browse/cdi-139 e https://issues.jboss.org/browse/weld-920

Esempio di operazioni di BeanManager:https://issues.jboss.org/browse/cdi-14?focusedcommentId=12601344 &page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel#comment-12601344

oorg.jboss.seam.faces.util.BeanManagerUtils

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top