当前位置: 首页 > 知识库问答 >
问题:

Java CPU消耗高

廉实
2023-03-14

我有一个Java pc应用程序,一旦加载相应的配置数据,CPU性能就会逐步提高。

基本有2个线程,一个主线程,一个副线程。在主线程中生成一个登录和一个数据加载,而在第二个线程中每10秒生成一次查询。如果会话启动但未加载数据,则第二个线程继续查询但性能最小。CPU消耗的增加是在加载数据后产生的,并且逐渐增加。

此外,如果再次加载数据,则消耗将降至最低,一旦加载,消耗将再次增加。

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
            }       
        }
    }

由于保密问题,我不能发布任何更多的代码。我看不出CPU的提升是从哪里来的。EventQueue、ActionListener、garbage collector等项目可能会导致此问题吗?

对于Java垃圾收集器,我使用以下参数:

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

共有2个答案

伍心水
2023-03-14

既然您提到了代码保密性,就像一些人在注释部分中建议的那样,您可以使用探查器工具来确定问题的来源。有一些优秀的免费或付费工具,以及与JDK一起使用的工具,如jvisualvm(这是一个单独的项目,现在可以作为独立的应用程序下载)。或者,您可以发布一个记录(Java飞行记录)文件,这是一个处理一些元数据的集合。

金瑞
2023-03-14

关于您发布的代码,唯一值得关注的是,您似乎正在ActionListener方法中运行所有业务逻辑,以响应按钮单击。如果//程序的其余部分花费了很长时间,那么GUI将冻结。然而,这似乎不是你所说的。

根据你对症状的描述,我想说你提到的任何事情都不可能是罪魁祸首。

IMO,最有可能的问题是在一些你没有给我们展示的代码中。例如,如果monitor_status()在某个大数据结构中持续积累内存,而程序中的某些内容是O(logn)(或者更糟),数据结构的大小。

还有一种可能是,持续增长的数据结构会导致垃圾收集器每次运行时花费越来越多的时间。但是,我希望这会导致java.lang.OutOfMemoryError:GC开销限制超出而不是持续的高CPU。

但是,注意,这只是推测,基于你给我们的极限信息。

我的忠告和其他人给出的一样:

  • 使用CPU探查器尝试查找大部分CPU使用的位置。
  • 使用内存探查器尝试查找内存泄漏的证据。
 类似资料:
  • 我们使用的是Spring kafka 2.7非阻塞重试机制。在Spring Kafka重试机制中,Kafka listenser使用来自main topic、Retry topic和DLT topic的消息,我们希望侦听器仅使用来自main和Retry topic的消息。 有没有简单的方法来进行设置? 因为我们不希望同一个消费者处理DLT消息。DLT还将被另一个进程使用,以发送请求通知。

  • 游戏进行外消耗道具 用法:传入需要消耗的道具列表已经对应的数量,则可以使用道具 消耗成功后,后台回吐消耗成功、失败的道具列表。如果消耗成功,则顺带返回一个流水号seq,用于标识此次消耗,此序列号可以用来进行回滚操作 var itemlist = [ { "id":1, //道具id "num":1, //数量 },

  • 我有一个服务员线程想使用RabbitMQ direct exchange向Java中的客户线程发送一道寿司,但是我的客户没有收到这道菜。下面是我的服务员用来发布寿司菜肴对象的方法: 请注意,<code>dishKey</code>作为参数传递,并在之前的if-else语句中被确定为<code>的“tamagoDishKey”</code>或<code>“ebiDishKey”的 以下是我的客户用来

  • 问题内容: 我想使用win32com扩展来实现python com服务器。然后从.NET内部使用服务器。我使用以下示例来实现com服务器,并且该服务器可以正常运行,但是当我尝试使用C#对其进行使用时,出现了FileNotFoundException并显示以下消息“为具有CLSID {676E38A6-7FA7-4BFF-9179的组件检索COM类工厂” -AE959734DEBB}由于以下错误而失

  • 问题内容: 我需要监视应用程序产生的线程消耗的内存量。如果贪婪的线程消耗太多内存,则想法是采取纠正措施。我已提到Java线程占用多少内存?。关于该链接的建议之一是在我尝试以下工作时使用。 我在四个线程上运行了很长时间。尽管作业不会连续地累积内存,但是所返回的值会不断增加,甚至不会下降。这意味着不会返回线程使用的堆上的实际内存量。它返回自线程启动以来在堆上为线程分配的内存总量。我的平台详细信息如下:

  • 我正在尝试Apache Camel技术,但遇到了麻烦。 我使用Jpa组件的轮询消费者as from(),并将实体上的@consumed注释设置为在流程结束时将其状态更改为“已成功处理”。它很好用。 但如果出现任何错误,我不想在数据库中设置“已成功处理”标志,而是设置“错误发生”之类的标志。 为了解决这个问题,我创建了一个带有处理器的“死信队列”,该处理器试图更改我正在进行的实体的状态,以便稍后保存