【问题标题】:optimize javafx code consuming large amount of memory and CPU优化消耗大量内存和CPU的javafx代码
【发布时间】:2014-08-21 10:20:03
【问题描述】:

下面的代码是一个筹款晚宴购买土地的代码,目的是显示购买土地的平方米(约2976平方米)的进度。每次购买一平方米时,该应用程序都会添加一个对应于实际 1 平方米的图像块。最终,瓷砖(约 2976 个)像网格一样填满,一旦完全购买,就完成了土地。

每个图块的大小约为 320 字节,总共有 2976 个图块。

我还在下面展示了一个图片示例。

这段代码(在 javafx 中)让我抓狂的是,它消耗了大约 90% 到 100% 的 1 个处理器,并且内存使用量随着瓦片的增加而不断增加,直到代码缓冲区内存不足和程序在一段时间后崩溃。这在筹款晚宴上是不可取的。

完整的代码可用于测试 您需要将布尔拆分更改为真假,这将为您拆分图像(大约 3000 张图像);

https://github.com/rihani/Condel-Park-Fundraiser/tree/master/src/javafxapplication3

使用所有内存和 CPU 的罪魁祸首是下面显示的 AnimationTimer() 函数,我想知道是否有人可以帮助我减少这段代码中的内存和 CPU 使用率。

简单解释一下下面的代码是如何使用的,土地被分成2个窗格,当第一个grid_pane1被填满时,第二个窗格grid_pane2开始然后填满。 还有一个闪烁的磁贴用于显示当前进度。

我正在使用 total_donnation ++;测试代码,但通常会使用 mysql 来提取在 findraising 晚餐期间提出的新值

AnimationTimer() 代码:

translate_timer = new AnimationTimer() {
            @Override public void handle(long now) {
                if (now > translate_lastTimerCall + 10000_000_000l) 
                {
                    old_total_donnation = total_donnation;
                    try 
                    {
//                        c = DBConnect.connect();
//                        SQL = "Select * from donations";
//                        rs = c.createStatement().executeQuery(SQL);
//                        while (rs.next()) 
//                        {total_donnation = rs.getInt("total_donnation");}
//                        c.close();

                        total_donnation ++;

                        if(total_donnation != old_total_donnation)
                        {
                            System.out.format("Total Donation: %s \n", total_donnation);

                            old_total_donnation = total_donnation;
                            if (!pane1_full)
                            {
                                grid_pane1.getChildren().clear();
                                grid_pane1.getChildren().removeAll(imageview_tile1,hBox_outter_last);                                
                            }
                            grid_pane2.getChildren().clear();
                            grid_pane2.getChildren().removeAll(imageview_tile2,hBox_outter_last);

                            for(i=0; i<=total_donnation; i++)
                            {
                                if (pane1_full){  System.out.println("Pane 1 has not been redrawn"); break;}
                                file1 = new File("pane1_img"+i+".png");
                                pane1_tiled_image = new Image(file1.toURI().toString(),image_Width,image_Height,false,false);
                                imageview_tile1 = new ImageView(pane1_tiled_image);
                                grid_pane1.add(imageview_tile1, current_column_pane1,current_row_pane1);   
                                current_column_pane1 = current_column_pane1+1;
                                if (current_column_pane1 == max_columns_pane1 )
                                {
                                    current_row_pane1 = current_row_pane1+1;
                                    current_column_pane1 = 0;
                                }
                                if (i == max_donnation_pane1 ){ pane1_full = true; System.out.println("Pane 1 full"); break;}
                                if (i == total_donnation)
                                {
                                    if (i != max_donnation_pane1)
                                    {

                                        hBox_outter_last = new HBox();
                                        hBox_outter_last.setStyle(style_outter);
                                        hBox_outter_last.getChildren().add(blink_image);

                                        ft1 = new FadeTransition(Duration.millis(500), hBox_outter_last);
                                        ft1.setFromValue(1.0);
                                        ft1.setToValue(0.3);
                                        ft1.setCycleCount(Animation.INDEFINITE);
                                        ft1.setAutoReverse(true);
                                        ft1.play();
                                        grid_pane1.add(hBox_outter_last, current_column_pane1,current_row_pane1);
                                    }
                                }
                            }

                            if (i < total_donnation)
                            {
                                total_donnation_left = total_donnation - max_donnation_pane1;
                                for(j=0; j<=total_donnation_left; j++)
                                {
                                    file2 = new File("pane2_img"+j+".png");
                                    pane2_tiled_image = new Image(file2.toURI().toString(),image_Width,image_Height,false,false);
                                    imageview_tile2 = new ImageView(pane2_tiled_image);
                                    grid_pane2.add(imageview_tile2, current_column_pane2,current_row_pane2);       
                                    current_column_pane2 = current_column_pane2+1;
                                    if (current_column_pane2 == max_columns_pane2 )
                                    {
                                        current_row_pane2 = current_row_pane2+1;
                                        current_column_pane2 = 0;
                                    }
                                    if (j == max_donnation_pane2 ){ System.out.println("Pane 2 full"); break;}
                                    if (j == total_donnation_left)
                                    {
                                        if (j != max_donnation_pane2)
                                        {
                                            hBox_outter_last = new HBox();
                                            hBox_outter_last.setStyle(style_outter);
                                            hBox_outter_last.getChildren().add(blink_image);

                                            ft = new FadeTransition(Duration.millis(500), hBox_outter_last);
                                            ft.setFromValue(1.0);
                                            ft.setToValue(0.3);
                                            ft.setCycleCount(Animation.INDEFINITE);
                                            ft.setAutoReverse(true);
                                            ft.play();

                                            grid_pane2.add(hBox_outter_last, current_column_pane2,current_row_pane2);
                                        }
                                    }  
                                }
                            }  
                            current_column_pane1 =0;
                            current_row_pane1=0;
                            current_column_pane2=0;
                            current_row_pane2=0;
                        }
                    }
                    catch (Exception ex) {}
                    translate_lastTimerCall = now;

                }
            }
        };

【问题讨论】:

    标签: image split grid javafx imageview


    【解决方案1】:
    1. 首先,您创建了许多永不停止的无限 FadeTransitions。随着时间的推移,这些加起来会导致内存和 CPU 泄漏。在开始新的过渡之前,您应该 stop() 过渡。或者,您只需要一个转换来插入 DoubleProperty 的值,然后将节点的不透明度绑定到此属性:

      DoubleProperty opacity = new SimpleDoubleProperty();
      Transition opacityTransition = new Transition() {
          protected void interpolate(double frac) {
              opacity.set(frac);
          }
      };
      
      // elsewhere
      hBox_outter_last.opacityProperty().bind(opacity);
      
    2. 您可能需要预先加载所有图像块,以避免在循环中从磁盘读取。

    3. 您在每个循环中都不必要地破坏和重新创建大部分场景。您应该修改您的代码以仅添加新图块,而不是全部删除它们并从头开始重新创建它们。

    4. 1234563 .

    【讨论】:

    • 谢谢托马斯。知道如何停止淡入淡出过渡。我试过 .stop 但什么也没做,也许我没有把它放在正确的地方。
    • 我使用了一种机制,其中只有新瓷砖是绿洲。但它也使用高 CPU 和内存。
    • 尝试将if(ft != null) { ft.stop(); } 放在ft = new FadeTransition(...); 之前。 ft1 也是如此。另外,您使用什么 JavaFX 版本?我认为以前存在不发布动画的错误,现在应该修复。或者,您只需要一个动画来为DoubleProperty 设置动画,然后将节点的不透明度绑定到这一属性。
    • 谢谢。你说的超出了我的重新绑定级别。欢迎举个例子。
    • CPU 使用率的罪魁祸首是淡入淡出过渡,如果我删除它,CPU 使用率会下降到 6%!顺便说一下 if(ft != null) { ft.stop(); } 什么都不做
    【解决方案2】:

    我有一个建议:

    • 请勿使用 2 个面板拆分图像。一种用于显示整个图像。第二个将是与第一个窗格重叠的网格窗格。因此,当购买一平方米时,相应网格单元的背景将变为透明。

    【讨论】:

    • 我喜欢这个想法。会试一试。我只剩下 1 天了 :)
    猜你喜欢
    • 2011-02-20
    • 1970-01-01
    • 2017-10-01
    • 1970-01-01
    • 2014-03-08
    • 2017-02-09
    • 1970-01-01
    • 2011-04-25
    • 1970-01-01
    相关资源
    最近更新 更多