Reputation: 172
I've recently noticed common lag spikes when running Java applications. The lag spikes occurred around every 10-15 seconds, and lasted anywhere from 1-5 seconds. I thought it could be because I'm creating a lot of processes. So I created a simple Java application that just creates a 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();
}
}
When I run it, the GPU usage goes from around 0-3% all the way to 95-100% used. If I don't create the Thread (at the end of Main()), the GPU isn't effected at all, but now I can't render anything on the window. I think it has to do with the BufferStrategy, but I am not sure. My GPU is NVIDIA GeForce GTX 1660 Ti, and my OS is Windows 10 Home.So my question is: Why is the GPU usage so high, and how can I fix it?
Upvotes: 1
Views: 1353
Reputation: 21
This fundamentally misunderstands how JFrame in swing is supposed to work. By using swing you're letting the operating system (and VM) do the handling of interactions and rendering. There is no need for a manual rendering thread at all.
Instead you should be overriding the paintComponent
function and use that graphics object to do your rendering (don't forget to call the super function as well to render the other bits). This will get called by the system when graphics drawing is required.
The only way something like this makes sense is when you're trying to render video to a JFrame manually. But even there the best approach would be to use existing component libraries to handle it for you.
Upvotes: 2
Reputation: 16999
Looks like while(running)
is doing way too many calls as it will run to max capacity of your system (could be way more than 60 FPS !).
Maybe you should only do the calls every 60 FPS via some kind of timer instead of using a "brutal" while loop ? Looks like this could be an answer to your problem: How do I set up a JFrame with a refresh rate?
Upvotes: 2