3

私は100万個の乱数を出力する非常に単純なJavaプログラムを持っています。Linuxでは、このプログラムがその存続期間中に使用する%CPUを観察しました。これは、98%から始まり、徐々に2%に減少するため、プログラムが非常に遅くなります。プログラムのCPU時間が徐々に短くなる原因となる可能性のある要因にはどのようなものがありますか?

で実行してみましたnice -20が、それでも同じ結果が表示されます。

編集:プログラムを実行すると/usr/bin/time -v、異常な量の非自発的なコンテキストスイッチ(588の自発的vs 16478の非自発的)が表示されます。これは、OSが他のより優先度の高いプロセスを実行させていることを示しています。

4

4 に答える 4

1

それは2つのことに要約されます:

  • I / Oは高価であり、
  • 数値の保存方法によっては、パフォーマンスにも悪影響を与える可能性があります。

主にSystem.out.println(randInt)100万回ループで実行している場合、それは高額になる可能性があります。I / Oは無料で提供されるものの1つではなく、出力ストリームへの書き込みにはリソースがかかります。

于 2012-12-12T23:38:33.307 に答える
0

まず、JConsoleまたはVisualVMを介してプロファイリングを行い、CPU%が低いときに実際に何が行われているかを確認します。コメントで述べたように、IOを待機している(ユーザー入力、SQLクエリに時間がかかるなど)など、ブロックされている可能性が高いです。

于 2012-12-12T23:36:39.107 に答える
0

アプリケーションがI/Oバウンドの場合-たとえば、ネットワーク呼び出しからの応答を待っている場合、またはディスクの読み取り/書き込み

于 2012-12-12T23:40:16.440 に答える
0

すべてのバランスを取りたい場合は、印刷する数値を保持するキューを作成してから、一方のスレッドでそれらを生成し(プロデューサー)、もう一方のスレッドでそれらを読み取って印刷する(コンシューマー)必要があります。これは、で簡単に実行できますLinkedBlockingQueue

public class PrintQueueExample {

    private BlockingQueue<Integer> printQueue = new LinkedBlockingQueue<Integer>();

    public static void main(String[] args) throws InterruptedException {
        PrinterThread thread = new PrinterThread();
        thread.start();
        for (int i = 0; i < 1000000; i++) {
            int toPrint = ...(i) ;
            printQueue.put(Integer.valueOf(toPrint));
        }
        thread.interrupt();
        thread.join();
        System.out.println("Complete");
    }

    private static class PrinterThread extends Thread {

        @Override
        public void run() {
            try {
                while (true) {
                    Integer toPrint = printQueue.take();
                    System.out.println(toPrint);
                }
            } catch (InterruptedException e) {
                // Interruption comes from main, means processing numbers has stopped
                // Finish remaining numbers and stop thread
                List<Integer> remainingNumbers = new ArrayList<Integer>();
                printQueue.drainTo(remainingNumbers);
                for (Integer toPrint : remainingNumbers)
                    System.out.println(toPrint);
            }
        }
    }
}

このコードにはいくつかの問題があるかもしれませんが、これがその要点です。

于 2012-12-12T23:59:28.830 に答える