2012-11-21 5 views
5

Mi piacerebbe avere un paio di approfondimenti su questo.Il POI Java Excel si interrompe dopo l'esecuzione multipla al quarzo

Ho un programma che legge e scrive da un database in un file di Excel. La sua esecuzione è basata su un timer che utilizza Quartz api e attivato ogni martedì della settimana. Il problema è che, quando l'ho testato programmandolo per eseguire il lavoro ogni ora, il programma si interrompe improvvisamente dopo alcune esecuzioni all'interno del processo di scrittura del file excel. Ecco la mia scrittura su codice Excel.

try { 
     FileInputStream file = new FileInputStream(excelFile); 
     POIFSFileSystem myFileSystem = new POIFSFileSystem(file); 
     HSSFWorkbook workbook = new HSSFWorkbook(myFileSystem); 
     HSSFSheet worksheet = workbook.getSheetAt(0); 
     this.cellStyle00 = workbook.createCellStyle(); 
     HSSFDataFormat df = workbook.createDataFormat(); 
     this.cellStyle00.setDataFormat(df.getFormat("00")); 

for(int i = 0;i<Access.size();i++){ 
     AccessorMethods SetGet = (AccessorMethods) 
        InstlibAccessor.get(i); 

    HSSFRow row = worksheet.createRow(worksheet.getPhysicalNumberOfRows()); 
    HSSFCell cell = row.createCell(0); 

    cell.setCellValue(new Double(SetGet.getOne())); 
    cell.setCellStyle(cellStyle00); 


    //other set value codes.... 

} 
FileOutputStream fileOut = new FileOutputStream(fileName + ".xls"); 
workbook.write(fileOut); 
fileOut.flush(); 
fileOut.close(); 

//catch statements follow 
//end 

L'uscita di uscita di linea di comando e NetBeans non indica alcun errore come la memoria, ecc ecc .. Il programma non finisce .. è solo, si ferma .. Come la JVM sta lavorando a un ciclo infinito ... Per gettare più luce sull'argomento, ecco il breve flusso del mio programma.

  1. l'utente esegue il programma di pianificazione
  2. Al momento desiderato lo scheduler esegue il programma (lo scheduler e "il programma" sono due diversi file di programmi/jar. Lo scheduler semplicemente chiama il vaso)
  3. Il programma inizia creando il file Excel
  4. quindi legge editori 1. il database contiene 80K righe
  5. Per ogni riga, se una certa condizione è soddisfatta, si legge di database 2 e 3
  6. quindi lo memorizza all'interno di un arra ylist oggetto 1000 alla volta (sto cercando di evitare qualsiasi problema di memoria quindi lo immagazzino per batch)
  7. Poi lo scrivo per batch, 1000 alla volta per eccellere (questa è la parte che si interrompe)
  8. dopo di esso completa la lettura e la scrittura, attende che lo scheduler lo richiami di nuovo ... Se raggiunge questo passo sono un programmatore felice =)

Ecco alcune osservazioni che ho trovato;

  1. Il programma di solito si ferma al 4 al 6 esecuzione del programma (che è dopo 4 o 6 ore di funzionamento del programma di pianificazione non stop)
  2. Si ferma in un punto casuale di scrittura in Excel come a la trecentomila riga o 24 o 15 ecc ecc ecc ...
  3. Questo errore non si verifica quando eseguo il programma senza uno schedulatore. Potrei eseguirlo manualmente tutto il giorno (l'ho fatto, non è stato molto divertente) senza errori.
  4. Il file di output excel visualizza 0 byte come dimensione
  5. Se ad esempio l'ho programmato per l'esecuzione ogni ora e per questa ora si è interrotto. Funzionerà ancora per le ore successive ma si fermerà e si fermerà in un punto diverso rispetto alla corsa precedente.

Cosa potrebbe aver causato questo problema. Una perdita di memoria forse o qualcosa di più semplice?

Ulteriori informazioni

ho implementato il programma di pianificazione Quartz importando la classe dell'altro programma ed eseguirlo come un lavoro.ecco il codice per il trigger

JobDetail job = newJob(ExtractorSchedulerJobUtilTester.class) 
      .withIdentity("job1", "group1") 
      .build(); 

    CronTrigger trigger = newTrigger() 
      .withIdentity("trigger1", "group1") 
      .withSchedule(cronSchedule("0 0/2 * 1/1 * ? *")) 
      .build(); 

    Date ft = sched.scheduleJob(job, trigger); 
     sched.start(); 

e il lavoro

public class ExtractorSchedulerJobUtilTester implements Job { 
    public void execute(JobExecutionContext context) 
     throws JobExecutionException { 
    theProgram program= new theProgram(); 

    program.main(); 

    JobKey jobKey = context.getJobDetail().getKey(); 
    } 
} 

E 'possibile che;

  1. L'applicazione è maxing la mia memoria e si blocca
  2. che sto usando solo un'istanza di "programma" nel mio lavoro al quarzo che viene inizializzata alla prima esecuzione del lavoro e tutte le successive esecuzioni del lavoro è referenziato da quell'istanza che quindi esaurisce la memoria.
  3. È collegato al database (AS400) (dubito perché si arresta mentre sta scrivendo l'Excel).
  4. Il computer diventa troppo stanco e decide di fare una pausa.

AGGIORNAMENTO - 12/28/2012

Buon Anno Ragazzi/Gals !!

dispiace mi c'è voluto del tempo per tornare in questo .. (Perché preoccuparsi di perdere tempo su questo quando il mondo è gonna fine il 21. E 'stato agrodolce quando non ha fatto)

ho fatto il profilo il mio programma con NetBeans Profiler ed ha ottenuto le seguenti figure con l'analizzatore di memoria

memory dump

ho notato nel primo grafico che il mio programma consuma circa 75 MB di dimensione heap per ogni iterazione (come indicato dalla tonalità rosa). Questo significa che la memoria consumata del programma aumenta di 75 MB per iterazione? Che, dopo poche iterazioni, consumerà così tanta memoria che influenzerà l'esecuzione del programma. Attualmente sto cercando di fare un deposito di heap. Lo posterò appena riesco a farlo funzionare.

Ulteriori informazioni: Ho provato a utilizzare il profiler con solo il Quartz in esecuzione (non attiva nulla) e l'utilizzo del sistema è relativamente basso e la dimensione non aumenta per ogni iterazione.

Sono finalmente riuscito a ottenere una discarica dell'heap. Ho fatto 2 discariche, il primo è quando è avvenuta la prima iterazione e la seconda è l'iterazione successiva. Ho notato che c'è una grande differenza tra le istanze di due dei miei classess come di seguito indicato

hash dump

Grazie!

+1

Qualche consiglio dalla profilazione? Stai iniziando una nuova VM ogni volta? Vedi anche questa [risposta] (http://stackoverflow.com/a/6310284/230513)? – trashgod

+2

In che modo lo scheduler esegue il programma? Avviare una nuova VM usando la riga di comando 'java' o semplicemente importare la classe Java del programma ed eseguire? Prova a fare in modo che lo scheduler funzioni ogni 5 o 10 minuti per il debug. Leggi questa domanda (http://stackoverflow.com/questions/337793/can-i-force-generation-of-a-jvm-crash-log-file) per sapere come scaricare i registri degli arresti anomali di JVM. –

+0

@AlexCheng. Ho appena importato la classe e l'ho eseguita come lavoro .. – ides

risposta

0

Dopo molte imprecazioni, preghiere e ricerche, penso di aver trovato una possibile soluzione a questo. Quello che ho fatto è stato aggiungere System.gc(); alla fine della mia classe di lavoro Quartz. Quindi, chiamando la garbage collection ogni volta che il programma termina il lavoro. È solo una possibile soluzione e non una risposta concreta perché sto ancora consumando molta memoria heap (credo che ci sia ancora qualche perdita di memoria da qualche parte nel caos del mio codice). Ma con lo System.gc(); sto consumando molto meno. Non sono sicuro di come ciò accada. Logicamente penserei che GC avrà effetto solo sull'allocazione della memoria e non sulle prestazioni della memoria del programma. Vedi l'immagine sotto; il grafico superiore è quello con GC mentre quello inferiore è quello senza.

enter image description here

Come si può vedere quello con il GC sta consumando meno memoria heap di quello senza. Presumo che l'utilizzo della memoria sarà sempre lo stesso con il GC, ma una volta che il GC viene chiamato lo spazio dell'heap utilizzato diminuirà. Utilizzerò questa soluzione fino a quando non verrà visualizzata una risposta migliore.

Problemi correlati