Domanda

Questa è la mia prima domanda su S.O.
Ho un problema molto strano.
Di seguito è riportato il mio problema ...

Scrivo metodo molto semplice che scrivere un testo in un file.
Naturalmente funziona bene la mia macchina (XP, 4CPU , jdk1.5.0_17 [SUN])
Ma è somtimes si blocca su un server operativo
(Linux Accounting240 2.4.20-8smp, 4CPU , jdk1.5.0_22 [SUN]).

uccidere -3 non funziona.
Ctrl + \ non funziona.

Quindi, non posso mostrare il dump thread.

Si blocca bene .. Quando ho solo scrivere qualche Thread.sleep (XX) a questo metodo, il problema è andato bene (?) ...
sonno (XX) pausa ... è successo di nuovo oggi con Thread.sleep (XX) ...

Lo sai questo problema? Avete il qualche soluzione a tale proposito? Grazie. : -)

P.S.
distribuzione Linux: Red Hat Linux 3.2.2-5
comando: java -cp. T

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileOutputStream;
import java.io.OutputStreamWriter;
import java.text.SimpleDateFormat;
import java.util.Date;

public class T {
private BufferedWriter writer = null;

private void log(String log) {
    try {
        if (writer == null) {
            File logFile = new File("test.log");
            writer = new BufferedWriter(new OutputStreamWriter(
                    new FileOutputStream(logFile, true)));
        }
        writer.write(new SimpleDateFormat("[yyyy-MM-dd HH:mm:ss] ")
                .format(new Date()));
        writer.write("[" + log + "]" + "\n");
        writer.flush();

         /*
                         *  this is ad hoc solution ???
                         */
        //Thread.sleep(10);
    } catch (Exception e) {
        e.printStackTrace();
    } finally {         
    }

}

public void test() {
    long startTime = System.currentTimeMillis();

    while (true) {
        log(String.valueOf(System.currentTimeMillis()));
        System.out.println(System.currentTimeMillis());
        try {
            //Thread.sleep((int) (Math.random() * 100));
        } catch (Exception e) {
            break;
        }

        if (System.currentTimeMillis() - startTime > 1000 * 5) {
            break;
        }
    }

    if (writer != null) {
        try {
            writer.close();
        } catch (Exception e) {
        }
    }
    System.out.println("OK");
}

public static void main(String[] args) {
    new T().test();
}
}
È stato utile?

Soluzione

Se la JVM non risponde di uccidere -3 allora non è il vostro programma ma la JVM che sta fallendo, che è male e richiederebbe un bug report a solarium.

Ho notato che si sta utilizzando un kernel 2.4.20-8smp. Questo non è un kernel tipico per un open source distribuzione Linux corrente, quindi vi suggerisco di dare un'occhiata al http://java.sun.com/j2se/1.5.0/system-configurations.html per vedere se si sta distribuendo ad una configurazione supportata. In caso contrario, si dovrebbe lasciare che i responsabili sanno!

Altri suggerimenti

Il primo passo è quello di ottenere un dump del filo in cui il programma è quando si "congela". Se questo fosse il Java 6, si potrebbe collegare jvisualvm o JConsole ad esso per impostazione predefinita e ottenere i stacktraces di tutti i fili da lì. Dal momento che è Java 5, si dovrebbe essere in grado di utilizzare il comando jstack per ottenere un dump filo (o si potrebbe abilitare JMX con una riga di comando opzione per collegare gli strumenti di cui sopra, ma non credo che ne vale la pena in questo caso) . In tutti i casi, premendo Ctrl-Break dalla console che ha lanciato l'applicazione può anche produrre un dump filo, a seconda dell'ambiente.

farlo più volte pochi secondi di distanza e quindi confrontare le discariche filo. Se sono sempre identici, allora sembra che l'applicazione è in fase di stallo; e la linea superiore della discarica mostrerà esattamente dove i fili stanno bloccando (che darà un buon indizio, quando si guarda a quella linea del codice, che le risorse stanno bloccati su).

D'altra parte, se le discariche filo cambiano di volta in volta, il programma non è strettamente un punto morto, ma sembra che sia in esecuzione in un ciclo infinito - forse una delle vostre condizioni di loop non è dichiarata propriamente i fili non uscire o qualcosa del genere. Ancora una volta, guardare il set di filo discariche per vedere quale area del codice di ciascun thread è un loop in giro, che vi darà un'idea della condizione del ciclo che non viene mai valutando ad una condizione di uscita.

Se il problema non è evidente da questa analisi, inviare indietro le discariche come sarà aiutare le persone a eseguire il debug del codice di cui sopra.

Credo che questa sia una condizione di competizione. Il while(true) forzerà la VM su Linux per scrivere e lavare continuamente, e il kernel di Linux VM cercherà di intercettare quelle chiamate e tamponare la scrittura. Questo renderà la spinloop processo in attesa che la syscall da completare; allo stesso tempo, sarà prelevato dallo scheduler e assegnato a un altro CPU (potrei sbagliarmi qui, tho). La nuova CPU cercherà di acquisire un blocco sulla risorsa, e tutto ciò si tradurrà in una situazione di stallo.

Questo potrebbe essere un segno di altri problemi a venire. Suggerisco:

  • prima di tutto, per chiarezza: spostare la creazione di file al di fuori del metodo log(). Questo è ciò che i costruttori sono per.

  • In secondo luogo, il motivo per cui stai cercando di scrivere in un file del genere? Sei sicuro che la tua logica di programma ha un senso, in primo luogo? Non preferisci scrivere i messaggi di log ad un contenitore (ad esempio, un ArrayList) e ogni XX secondi di dettagli che su disco in un thread separato? In questo momento si sta limitando la vostra capacità di registrazione per la velocità del disco:. Qualcosa che si potrebbe voler evitare

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