Java中的CPU负载不变

时间:2015-04-23 13:31:44

标签: java load cpu-usage

如何让CPU利用率更加稳定?

我想用java生成一个人工负载,它会强调CPU并消耗RAM。资源消耗保持常数非常重要。因此,重点在于CPU。 RAM是次要的。我之所以选择Java,因为它可以在几乎所有平台上运行。我有兴趣看看我的计算机上的这种负载是否经常消耗每小时CPU利用率的20%,但在我的第二台计算机上可能是30%。为了实现更高的CPU利用率并强调多个内核,程序可以运行多个线程。

我已经在stackoverflow上阅读了generate CPU load in JavaArtificial generation of cpu load in Java

这是我的代码。我有一个类来控制线程,一个类用于提供负载的线程。我选择计算阶乘来压力CPU。

package loadPackage;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;


public class LoadController {

    public static void main(String[] args) {
        int threads = 16;
        int runlength = 100000;
        long time;
        try {
            runlength = Integer.parseInt(args[0]);
        } catch (Exception e) {
            System.out.println("Only integer allowed!");
        }
        time = System.currentTimeMillis() + runlength;
        ExecutorService executor = Executors.newFixedThreadPool(threads);
        for (int i = 0; i < threads; i++) {
            Runnable worker = new Workload(time);
            executor.execute(worker);
          }
        executor.shutdown();
        while (!executor.isTerminated()) {
        }

    }

}



package loadPackage;

import java.math.BigInteger;

public class Workload implements Runnable  {
    private long time;

    public Workload(long time) {
        this.time = time;
    }

    public void run() {
        while (System.currentTimeMillis() < time) {
            BigInteger fact = BigInteger.valueOf(1);
            for (int i = 1; i <= 6000; i++) {
                fact = fact.multiply(BigInteger.valueOf(i));
            }
            try {
                Thread.sleep(200);
            }
            catch (Exception localException1) {}
        }
    }

}

我的测量工具每5分钟测量一次(不是样本,而是这个时期的平均利用率)。因此可以容忍最小的变化。但是,有时它显示出我无法解释的强烈峰值。

问题一:您知道为什么我的CPU利用率会如此强劲吗?

问题二:我可以使用哪些编程技术来最小化CPU利用率偏差?


[2015年4月30日更新]

我怀疑一个原因:超线程我有一台带超线程的HP笔记本电脑i7四核(任务管理器显示8个虚拟内核)。我使用的测量工具具有超线程校正功能,并显示实际消耗的资源。然而,这是猜测, VisualVM仅测量虚拟核心消耗 !?我试图在BIOS中停用超线程来证明我的假设的正确性。但是由于HP,此选项在BIOS中的配置下不可用。你怎么看,超测量偏差的原因是什么?

替代方法:不同的JVM 我使用标准JVM“Java HotSpot(TM)64位服务器VM”。使用更紧凑的JVM会有助于更稳定的Java资源消耗吗?

3 个答案:

答案 0 :(得分:0)

CPU利用率由操作系统管理,因此AFAIK无法将java线程“锁定”到特定处理器(这将导致持续利用)。 当你在linux系统上打开htop时,你会看到这一点。线程将像板球一样跳过你的cpus。 我从未设法在java中实现这种持续利用,仅在C(++)

答案 1 :(得分:0)

我建议您在此过程中启动visual vm。您将能够跟踪GC活动。如果您看到GC峰值消耗的CPU时间与您之前看到的一样,那么您可以确定原因。

答案 2 :(得分:0)

我知道这有点旧线程,但如果您仍然感兴趣,请查看https://github.com/OpenHFT/Java-Thread-Affinity处的OpenHFT Java线程关联库。我已经用它来将Java线程固定到给定的内核,并为某些应用程序提供良好的性能(CPU使用率)。

正如作者博客(http://vanillajava.blogspot.com/2011/12/thread-affinity-library-for-java.html)中提到的具有隔离内核(您可以在启动时传递isolcpus)也会有所帮助。