简体   繁体   中英

High CPU consumption in java

I have an java pc application, that once loaded the corresponding configuration data, the CPU performance increases progressively.

There are basically 2 threads, one main and one secondary. In the main thread a login and a data load are generated, while in the second a query is generated every 10 seconds. If the session starts but the data is not loaded, the second thread continues to query but the performance is minimal. The increase in CPU consumption is generated once the data is loaded and increases progressively.

In addition, if data is loaded again, consumption drops to a minimum and once loaded it increases again.

public static void main (String [] args)
    {
        EventQueue.invokeLater(new Runnable() {
            public void run() {
                try {
                    MainWindow window = MainWindow.getInstance ();
                        window.get_headerPanel().get_buttonLoad().addActionListener( new ActionListener() {
                        
                        @Override
                        public void actionPerformed(ActionEvent e) {
                            
                            if (JOptionPane.YES_OPTION ==  JOptionPane.showConfirmDialog(window
                                                                                         ,"Changes made will be lost \ nDo you want to continue?"
                                                                                         ,"Load device configuration"
                                                                                         , JOptionPane.YES_NO_OPTION)) {                            
                                Device.getInstance().reset ();
                                window.reset();
                                
                                if (CommManager.getInstance().load())
                                    //Rest of the program
                            }
                        }
                   };
               } catch (Exception e) {
                   e.printStackTrace();
               }
            }
        });
    }
    
@Override
    public void run() {

        while (true) {
            
            if (openSession && Protocol.command == false) {
                System.out.print("MONITOR STATUS\n");
                monitor_status ();
            }
            
            try {
                Thread.sleep(10000);
            }
            catch (Exception e) {
                // TODO: handle exception
            }
            catch (Throwable t) {
                // TODO: handle exception
            }       
        }
    }

I cannot post any more code due to confidentiality issues. And I can't see where that CPU boost is coming from. Could any of these items like EventQueue, ActionListener, garbage collector... be causing this problem?

For the Java Garbage Collector I use the following parameters:

java -jar -XX:+UseG1GC -XX:MaxGCPauseMillis=5000 -XX:ParallelGCThreads=20 -XX:ConcGCThreads=5 -XX:InitiatingHeapOccupancyPercent=75 .\code.jar

Since you mentioned code confidentiality, as some people suggested in the comment section, you may use a profiler tool to pin point where the issue is coming from. There are some excellent free or paid tools out there as well as those coming together with the JDK like jvisualvm (this is a separate project which can be downloaded as an stand-alone application now). Alternatively you could post a recording (Java flight recorder) file which is a collection of process some meta data.

The only concerning thing about the code that you have posted is that you appear to be running all of your business logic in the ActionListener method in response to a button click. If the // Rest of the program takes a long time, then the GUI will freeze. However that doesn't appear to be what you are talking about.

Based on your description of the symptoms, I would say that none of the things you mentioned is a likely culprit.

IMO, it is most likely that the problem is in some code you haven't shown us. For example, what if monitor_status() was continually accumulating memory in some big data structure, and something in the program is O(log N) (or worse) on the size of the data structure.

It is also possible that a continually growing data structure would cause the garbage collector to take more and more time, each time it ran. However, I would expect that to result in an java.lang.OutOfMemoryError: GC overhead limit exceeded rather than continually high CPU.

However, note that this is just speculation, based on the limit information you have given us.


My advice is the same as others have given:

  • Use CPU profiler to try to find where most of the CPU is used.
  • Use a Memory profiler to try to find evidence of a memory leak.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM