我有一个非常简单的java程序,打印出100万个随机数。在linux中,我观察了该程序在其生命周期中所占的%CPU,它从98%开始然后逐渐降低到2%,从而导致程序非常慢。有哪些因素可能导致程序逐渐减少CPU时间?
我已尝试使用nice -20
运行它,但我仍然看到相同的结果。
编辑:用/usr/bin/time -v
运行程序我看到异常数量的非自愿上下文切换(588自愿与16478非自愿),这表明操作系统正在让其他更高优先级的进程运行。
答案 0 :(得分:1)
归结为两件事:
如果你主要在循环中做System.out.println(randInt)
一百万次,那么这会花费很多。 I / O不是免费提供的东西之一,写入任何输出流都需要资源。
答案 1 :(得分:0)
我首先要通过JConsole或VisualVM进行分析,看看它在CPU%较低时的实际操作情况。正如评论中提到的那样,它很有可能阻塞,例如:等待IO(用户输入,SQL查询需要很长时间等)
答案 2 :(得分:0)
如果您的应用程序受I / O限制 - 例如等待来自网络调用的响应,或磁盘读/写
答案 3 :(得分: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);
}
}
}
}
此代码可能存在一些问题,但这是它的要点。