3

I have a very simple java program that prints out 1 million random numbers. In linux, I observed the %CPU that this program takes during its lifespan, it starts off at 98% then gradually decreases to 2%, thus causing the program to be very slow. What are some of the factors that might cause the program to gradually get less CPU time?

I've tried running it with nice -20 but I still see the same results.

EDIT: running the program with /usr/bin/time -v I'm seeing an unusual amount of involuntary context switches (588 voluntary vs 16478 involuntary), which suggests that the OS is letting some other higher priority process run.

4

4 回答 4

1

它归结为两件事:

  • I/O 很昂贵,并且
  • 根据您存储数字的方式,这也会对性能产生不利影响。

如果您主要System.out.println(randInt)在循环中执行一百万次,那么这可能会变得昂贵。I/O 不是免费提供的东西之一,写入任何输出流都会消耗资源。

于 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 回答