开发者

Java reduce CPU usage

Greets-

We gots a few nutters in work who enjoy using

while(true) { //Code } 

in their code. As you can imagine this maxes out the CPU. Does anyone know ways to reduce the CPU utilization so that other people can use the server as well.

The code itself is just constantly polling the internet for updates on sites. Therefore I'd imagine a little sleep method would greatly reduce th开发者_JAVA百科e the CPU usage.

Also all manipulation is being done in String objects (Java) anyone know how much StringBuilders would reduce the over head by?

Thanks for any pointers


A lot of the "folk wisdom" about StringBuilder is incorrect. For example, changing this:

String s = s1 + ":" + s2 + ":" + s3;

to this:

StringBuilder sb = new StringBuilder(s1);
sb.append(":");
sb.append(s2);
sb.append(":");
sb.append(s3);
String s = sb.toString();

probably won't make it go any faster. This is because the Java compiler actually translates the concatenation sequence into an equivalent sequence of appends to a temporary StringBuilder. Unless you are concatenating Strings in a loop, you are better of just using the + operator. Your code will be easier to read.

The other point that should be made is that you should use a profiler to identify the places in your code that would benefit from work to improve performance. Most developers' intuition about what is worth optimizing is not that reliable.


I'll start off with your second question, I would like to agree with the rest that StringBuilder vs String is very much dependent on the particular string manipulations. I had "benchmarked" this once and generally speaking as the amount of new string allocations went up (usually in the form of concatenations) the overall execution time went up. I won't go into the details and just say that StringBuilder turned out to be most efficient overtime, when compared to String, StringBuffer, String.format(), MessageFormat...

My rule of thumb is that whenever I wish to concatenate more than 3 string together I always use StringBuilder.

As for your first question. We had a requirement to bring CPU usage to 5%. Not an easy task. We used Spring's AOP mechanism to add a Thread.sleep() to before any method execution of a CPU intensive method. The Thread.sleep() would get invoked only if some limit had been exceeded. I am sorry to say that the computation of this limit is not that simple. And even sorrier to say that I still have not obtained the permission to post it up on the net. So this is just in order to put you on an interesting but complicated track that has proven to work over time.


How often do those sites update? You're probably really annoying the hosts. Just stick a Thread.sleep(60 * 1000); at the end of the loop and you can avoid this. That'll poll them once a minute—surely that's enough?


Make it wait some time before firing again, like this:

while(true) { 
  //Code 
  Thread.sleep (1000); //Wait 1 second
} 

As for the second question, it would reduce memory and possibly CPU usage as well, but the gains really depend on what's happening with those strings.


A sleep would reduce the CPU usage. As for the StringBuilders they could lower the memory usage and improve performance.


You could also try

Thread.yield()


If their code is in a separate JVM and is running on Linux or some other Unix, require them to run their program at nice 20.

Or you could have them run inside a virtual machine like VirtualBox and use it to limit the processor utilization.

Or you could fire them if they continue burn cycles like that instead of using some event-driven model or Thread.sleep.


Never assume something you see in the code is bad (or good) for performance. Performance issues are notoriously deceptive.

Here's an easy way to see for sure what is taking the time.


  1. What sites is the code polling? Do they support an RSS push?
  2. If they do, then there is no need to poll the sites, and instead plug a module to wait for updates. The current method then waits using wait();
  3. The new module then notifies the object with this method using notifyAll().
  4. Admittedly this is some extra work, but it saves a whole lot of bandwidth and computation.
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜