运行 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 时,这样的事情才有意义。但即便如此,最好的方法还是使用现有的组件库来为您处理。
我最近注意到 运行 宁 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 时,这样的事情才有意义。但即便如此,最好的方法还是使用现有的组件库来为您处理。