【问题标题】:Process 'javaw' taking up 95%+ of CPU usage [closed]进程“javaw”占用 95% 以上的 CPU 使用率 [关闭]
【发布时间】:2014-04-14 02:19:27
【问题描述】:

我有一个 java 游戏,它在启动时运行至少 94% 的 CPU。考虑到程序只有 124kb,这确实是一个疯狂的数字。可能的问题是它实现了三种线程。

  • 作为服务器接收和发送数据包;
  • 一个作为客户;
  • 和主游戏线程。

可能有很多不同的可能性来解释为什么会出现这种情况,但我的猜测是坚持 Thread 的想法。欢迎提出任何降低此数字的想法和建议,并非常感谢

CPU:Intel Core 2 Duo,2.66Ghz RAM,2gb。


注意:这发生在许多计算机上,但游戏运行流畅。


编辑:在回复一个答案时,我没有使用任何库,并且我以类似的方式创建了我的线程。客户端和服务器线程如下:
public class Client implements Runnable {
  public boolean running;
  public DatagramSocket socket;

  public Client() {
    running = true;
    socket = new DatagramSocket(/*whatever params*/);
    new Thread(this).start();
  }
  public void run() {
    byte[] data = new byte[1024];
    while(running) {
      socket.receive(data);
      parsePacket(data);
    }
  }
  public void parsePacket(byte[] data) {
    // Does all the packet parsing things.
    // The client modifies the level.
    // The server just spreads things to every client. (could be the server if multiple connections are live?)
  }
}

但是,当您检查线程是否被中断时,不是检查是否且仅当线程暂停时吗? - 这就是中断线程的意思,对吧?

在主游戏循环结束时使用Thread.sleep(50) 会有什么好处吗?仍然开放以寻求合理的修复。

【问题讨论】:

  • jvm 在 CPU 消耗较高时创建了多少线程?还可以通过监控 GC 活动来检查 jvm 是否在只做 GC 时保持忙碌
  • 大小通常不代表 CPU 负载。 while (true) {} 很容易占用 100% CPU!

标签: java multithreading performance cpu-usage


【解决方案1】:

这是一个性能调优问题,需要整个代码库都知道您在做什么会导致处理器加速。现在我们知道您已经编写了一个启动三个线程的计算机程序。所以我打赌它在这三个线程之一中,因为这就是我们真正知道的。我们甚至不知道它基于什么游戏库。没有任何真正的代码,就无法提供任何真正的帮助。

无论如何,这就是你要开始弄清楚哪个线程正在被遗忘的方法。通常你会这样写一个主线程:

public class MainGameLoop implements Runnable {

    public void startupGame() {
       long start = System.currentTimeMillis();
       doStartUpGame();
       long end = System.currentTimeMillis();
       System.out.printf("Start up took %,d%n", end - start );
    }

    public void run() {
        startUpGame();
        while( !Thread.currentThread().isInterrupted() ) {
            long start = System.currentTimeMillis();
            doGameLogic();
            long duration = System.currentTimeMillis() - start;
            System.out.printf("Processing took %,d ms %n", duration );
            if( duration < frameRate ) {
               Thread.sleep( frameRate - duration );
            } else {
               System.out.printf("Game loop took longer than it should by %,d ms%n", duration - frameRate );
            }
        }
    }
}

在所有线程上执行此操作,然后查看三个线程中的哪一个占用了如此多的 CPU。之后,您可以开始将范围缩小到占用 CPU 的部分。对 doGameLogic 等之外的每个子进程重复此过程。

【讨论】:

  • Thread.isInterrupted() 是当有人调用 thread.interrupt() 时设置的标志,当您希望线程关闭时完成。 Thread.interrupt() 不会关闭线程,它只是请求线程停止。阅读 Java API 中的线程,因为从 API 中理解它们并不难。 sleep 调用可防止您的线程烧毁 CPU,因为您不再需要以游戏的 frameRate 更新屏幕。如果没有睡眠,您实际上是在编写 while(true) { bang the processor }。并且 InterruptedException 非常重要并且与上面联系在一起。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-10-19
  • 1970-01-01
  • 1970-01-01
  • 2015-10-29
  • 2010-11-19
  • 2016-03-22
相关资源
最近更新 更多