运行 Java 应用程序时 GPU 使用率高

High GPU usage While Running Java Application

我最近注意到 运行 宁 Java 应用程序时常见的滞后峰值。滞后峰值大约每 10-15 秒出现一次,并持续 1-5 秒。我认为这可能是因为我正在创建很多流程。所以我创建了一个简单的 Java 应用程序,它只创建了一个 window:

public class Main extends Canvas {
    private static final long serialVersionUID = 1L;
    public JFrame frame = new JFrame();
    public Main() {
        frame.add(this);
        frame.setSize(1000, 750);
        frame.setLocationRelativeTo(null);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setVisible(true);
        new Thread(() -> run()).start();
    }
    public void run() {
        boolean running = true;
        while(running) {
            BufferStrategy bs = getBufferStrategy();
            if(bs != null) {
                Graphics g = bs.getDrawGraphics();
                render(g);
                g.dispose();
                bs.show();
            } else {
                createBufferStrategy(3);
            }
        }
    }
    public void render(Graphics g) {
        g.setColor(Color.green);
        g.fillRect(0, 0, getWidth(), getHeight());
    }
    
    public static void main(String[] args) {
        new Main();
    }
}

当我 运行 它时,GPU 使用率从大约 0-3% 一路上升到 95-100%。如果我不创建线程(在 Main() 的末尾),GPU 根本不会受到影响,但现在我无法在 window 上渲染任何内容。我认为这与 BufferStrategy 有关,但我不确定。我的 GPU 是 NVIDIA GeForce GTX 1660 Ti,我的 OS 是 Windows 10 Home.So 我的问题是:为什么 GPU 使用率这么高,我该如何解决?

看起来 while(running) 执行的调用太多了,因为它会 运行 您系统的最大容量(可能超过 60 FPS!)。

也许你应该只通过某种计时器每 60 FPS 调用一次,而不是使用“残酷的”while 循环? 看起来这可能是您问题的答案:How do I set up a JFrame with a refresh rate?

这从根本上误解了 swing 中的 JFrame 应该如何工作。通过使用 swing,您可以让操作系统(和 VM)处理交互和渲染。完全不需要手动渲染线程

相反,您应该覆盖 paintComponent 函数并使用该图形对象进行渲染(不要忘记调用 super 函数来渲染其他位)。当需要绘制图形时,系统会调用此方法

只有当您尝试手动将视频呈现到 JFrame 时,这样的事情才有意义。但即便如此,最好的方法还是使用现有的组件库来为您处理。