Domanda

Ho scritto uno script di caricamento del database in ColdFusion e sto avendo un problema che lo script viene eseguito lentamente la memoria. Ho diviso ogni carico tabella in proprio thread con e sto chiamando il garbage collector quando cali di memoria al di sotto del 50% (avendo cura di avere 30 secondi tra GC () le chiamate per evitare che il garbage collector da monopolizzavano memoria) .

ho creato un CFC per contenere tutte le domande necessarie dallo script. Lo script chiama la funzione CFC appropriato che poi ritorna la query, alcune delle quali sono più di 2 MB. Quando mi guardo allo Server Monitor nella vista dettagli della pagina di memoria per Thread attivi, sembra che il mio CFC conservi una copia della query in memoria anche se ho varscoped la variabile di query e la variabile andato fuori portata alla fine della funzione. Inoltre, ho una copia della query in memoria nel mio thread. Quindi sono lasciato con quella che appare come due copie della query in memoria. E 'davvero questo quello che sta succedendo? Se lo è, come posso eliminare una copia della query dalla memoria?

È stato utile?

Soluzione

C'è un sacco di potenziali problemi qui, ma cercherò di sottolineare alcune delle cose più importanti da prendere in considerazione:

  1. Perché i fili? Avete bisogno i fili? C'è un certo punto in cui probabilmente stai armeggiare troppo per il tuo bene.
  2. forzando manualmente la raccolta dei rifiuti non è necessariamente una buona idea. Tune la JVM di svolgere la sua garbage collection automatica, ma non esagerare, neanche. Garbage Collection tende ad essere costoso, e può influire sulle prestazioni della vostra applicazione se è in esecuzione troppo frequentemente.
  3. Come stai un'istanza di tua CFC? Se si istanziare la CFC su ogni richiesta per la query, si sta andando a problemi di esperienza RAM nel corso del tempo, una perdita di memoria lento come i CFC vengono caricati nella RAM fino troppo in fretta per la garbage collection di tenere il passo. La cosa migliore è quello di rendere questo un Singleton. (Es., Impostarlo nella portata di applicazione).
  4. Essere consapevoli del fatto che var-scoping una variabile non (per quanto ho capito bene) liberare automaticamente la memoria non appena smette di essere utilizzata la variabile. La memoria è ancora riservata, anche se è probabile che in qualche modo contrassegnato come facenti parte di una generazione di breve durata in modo che (probabilmente?) Essere pulito più velocemente. Ma questo non garantisce nulla.
  5. Se stai guardando thread attivi, è anche possibile che la query non sta per essere cancellato fino alla fine della richiesta - non necessariamente la fine della chiamata di funzione. Sembra l'impazienza che si potrebbe motivare aspettarsi una query per morire immediatamente non appena la chiamata di funzione è terminata.
  6. query vengono passati per riferimento , non per valore. Dovrebbe essere impossibile ottenere 2 copie della query in memoria, a meno che non si sta in qualche modo utilizzando duplicati () o una funzione simile a copiare esplicitamente la query.

La query viene probabilmente restituisce un puntatore alla query dalla sua dichiarazione cfreturn. Che query non sarà ripulito fino a quando tutti i processi sono fatti riferimento di esso. Quindi, se passa la query a qualche altro processo, non avete intenzione di ottenere tale query ripulito la memoria. Se si imposta la query a una variabile di sessione, per esempio, che il puntatore non sta andando da nessuna parte fino a quel variabile di sessione è andato, non importa quanto spesso si tenta di raccolta forza spazzatura.

A pochi cose da considerare.

Altri suggerimenti

Ho avuto un problema simile con elaborazione di un gran inserimento dati, in cui ogni riga richiede una trasformazione che coinvolge più CFC. Sembra che esimo ResultSet JDBC, Dichiarazione e di collegamento riferimenti creato da vengono mantenuti fino alla fine della richiesta. Ciò significa che la variabile che annulla i interrogazione non ha alcun effetto sul l'utilizzo della memoria. Il modo in cui ho ottenuto intorno a questo è stato quello di effettuare una chiamata gateway per una funzione CFC ai processi di 100 righe, allora quella funzione fa un'altra chiamata gateway per i prossimi 100 righe ecc fino a quando tutte le righe vengono elaborati. Poiché ogni chiamata porta singola esce in realtà, rilascia tutti i suoi manici e che la memoria viene recuperata.

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