0

I've been working on an android game for awhile now. I have the basic game implemented so now I'm going back and trying to optimize. It seems like the battery drain and CPU usage are too high for what I'm doing. I really only have my main thread and then all the drawing and updating is done on a separate thread.

Below is the code for the actual game thread that does updating and all the drawing. All of the actual code has been removed, what's left is what I've been experimenting with to figure out the abnormal CPU usage/battery drain.

So basically if I start the below thread with only an infinite while loop the app uses about 315mAh or about 9% of my phones battery in 30 minutes of use. If I start the thread with no code inside the run method so that it expires after one run through it uses roughly 70mAh or 2% of the phone battery in the same amount of time. The CPU usage also jumps from 2%-3% without the thread running to about 14%-15% when the thread running and just running the infinite loop.

To summarize it seems like running the thread with only an infinite while loop, that does nothing, increases the battery usage by 7% over 30 minutes. I don't see how this is possible and think I must be missing something. I'll keep working to figure this out but there's no more code to take out. If anyone has any suggestions or can provide some insight as to why this is happening I'd greatly appreciate it. Thanks in advance.

class InnerThread extends Thread
    {
        public InnerThread()
        {
            super();
        }

        public void run()
        {
           while(true){}
        }
    }
Envenge
  • 41
  • 7

3 Answers3

1

while(true) is a classical endless loop and probably not required in Java.

it does not even matter on which thread it runs, it's most likely draining the juice.

see Are "while(true)" loops so bad?

Martin Zeitler
  • 1
  • 19
  • 155
  • 216
  • Hi, the while(true) loop is meant to be endless so it keeps the thread running to test battery drain of the thread by doing only a small amount of work. I wanted to minimize the amount of work the thread is doing to see how low I can get the battery drain and still have the thread running. – Envenge Nov 18 '18 at 23:49
  • 2
    @Envenge You're not minimizing the work. Spinning in `while(true)` is just as much work as performing some useful calculation. – Kevin Krumwiede Nov 18 '18 at 23:52
  • 1
    @Envenge as the other answer suggests, unless adding some easing... it will run at the maximum iteration speed and drain the battery rigorously. this is something which one possibly can do on an AC powered machine, but not a mobile device. there it's better to perform processing only when required. – Martin Zeitler Nov 18 '18 at 23:52
  • eg. when adding `Thread.sleep(500)` it would still iterate twice per second. but this is a workaround. reconsidering the fundamental business logic suggested. – Martin Zeitler Nov 18 '18 at 23:57
  • I've played with this a bit already but haven't quite found the best way to do it without slightly interfering with the gaming performance. I'll look into reorganizing the code and try putting the thread to sleep periodically. Thanks for your quick responses! – Envenge Nov 19 '18 at 00:00
  • @Envenge you'd need to identify how often you even need whatever code runs in there. possibly adding a service would help; this would also have it's own thread and keeps running. try to make it event-based or checkout the source code of other game engines, how they handle it. – Martin Zeitler Nov 19 '18 at 00:05
1

Loops with no delay or pacing are notorious for hogging CPU and battery. Think carefully about whether you really need to be processing continuously, or if once per frame, once per arbitrary time interval, or once each time some external event occurs would be sufficient. Try adding a small arbitrary delay in the loop, and you'll probably see an immediate improvement.

Many games use a main game loop. That's a searchable term. Basically, an endless loop performs some computations, draws a frame, then usually sleeps for some time. (See SystemClock.sleep() vs. Thread.sleep().) Your main loop could pass a frame number and timestamp to the rest of your code. You might compute the positions of moving objects every frame, but you could do more complex things like update the AI of your enemies only at certain intervals of time or frames. If you use a game engine like Unity, the main loop is still there, but you don't write it yourself. You just write the code that it calls every frame.

Kevin Krumwiede
  • 9,868
  • 4
  • 34
  • 82
  • So I thought this may be the issue. I tested and it is running at about 13,000 frames per second which is obviously way too high for what I need. The ideal is to get it going at 60 FPS. I've tried using System.nanotime to maintain the framerate but in that case the majority of the game code is running at 60 FPS but the code to keep the framerate maintained is still runnning at 13,000+ FPS. I can try maintaining the framerate in a different way, what is the preferred way to do a delay? SystemClock.sleep? – Envenge Nov 18 '18 at 23:57
  • @Envenge Edited. – Kevin Krumwiede Nov 19 '18 at 00:36
  • Really appreciate your help. I have experience with game loops and have one implemented I just removed the actual code to try to get the least possible code in my loop to make sure I wasn't having a memory leak or something, somewhere inside, that was causing the spike in cpu usage and battery drain. Multi-threading is a fairly new concept to me which I'm still trying to fully utilize. There's definitely a lot to learn I again appreciate your time and patience to explain things that may seem fairly obvious. – Envenge Nov 19 '18 at 04:12
0

I went through and edited my code. Utilizing thread.sleep to limit the overall drawing and updating code to 60 frames per second. Also I made use of the Object.wait() and Object.notify() methods to reduce the unnecessary processing of the thread. I've seen huge improvements, thanks for the help, I really appreciate it. My problem was most definitely that I was wasting battery and CPU power processing nothing.

Envenge
  • 41
  • 7