Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/performance/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/user-interface/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Performance JavaFX吃掉了我的记忆?_Performance_User Interface_Memory_Javafx_Javafx 8 - Fatal编程技术网

Performance JavaFX吃掉了我的记忆?

Performance JavaFX吃掉了我的记忆?,performance,user-interface,memory,javafx,javafx-8,Performance,User Interface,Memory,Javafx,Javafx 8,在对这个标题感到沮丧之前,我想澄清一下,我是JavaFXUI的新手。我已经使用Swing做了9年的开发人员,现在我决定尝试一下JavaFX。网上的例子表明,与Swing相比,JavaFX确实可以创建漂亮的GUI。也许我试图以错误的方式创建和部署GUI,但有一件事是肯定的。JavaFX窗格的加载速度比Swing慢,并且占用更多内存。同样的GUI是用JAVAFX重新设计的,几乎需要200Mb,而Swing GUI只需要50Mb 这里我给出一个代码示例,说明如何使用FXML以编程方式创建GUI pub

在对这个标题感到沮丧之前,我想澄清一下,我是JavaFXUI的新手。我已经使用Swing做了9年的开发人员,现在我决定尝试一下JavaFX。网上的例子表明,与Swing相比,JavaFX确实可以创建漂亮的GUI。也许我试图以错误的方式创建和部署GUI,但有一件事是肯定的。JavaFX窗格的加载速度比Swing慢,并且占用更多内存。同样的GUI是用JAVAFX重新设计的,几乎需要200Mb,而Swing GUI只需要50Mb

这里我给出一个代码示例,说明如何使用FXML以编程方式创建GUI

public class PanelCreator {

   private FXMLPane<LoginPaneController>           loginFXML;
   private FXMLPane<RegistrationPaneController>    registerFXML;
   private FXMLPane<EmailValidationPaneController> emailValidationFXML;

   public PanelCreator() {
      this.rootPane = rootPane;
      try {
        loginFXML           = new FXMLPane<LoginPaneController>("Login.fxml");
        registerFXML        = new FXMLPane<RegistrationPaneController>("Register.fxml");
        emailValidationFXML = new FXMLPane<EmailValidationPaneController>("EmailValidation.fxml");
      } catch (IOException e) {e.printStackTrace();} // catch
   } // Constructor Method

   public Pane getLoginPane() {
      return loginFXML.getPane();
   } // getLoginPane()

   public Pane getRegisterPane() {
      return registerFXML.getPane();
   } // getRegisterPane

   public Pane getEmailValidationPane() {
      return emailValidationFXML.getPane();
   } // getEmailValidationPane

   public LoginPaneController getLoginPaneController() {
      return loginFXML.getController();
   } // getLoginPaneController()

   public RegistrationPaneController getRegistrationPaneController() {
      return registerFXML.getController();
   } // getRegistrationPaneController()
} // class PanelCreator
公共类PanelCreator{
私有FXMLPane loginFXML;
私有FXMLPane寄存器XML;
专用FXMLPane emailValidationFXML;
公共面板创建者(){
this.rootPane=rootPane;
试一试{
loginFXML=newfxmlpane(“Login.fxml”);
registerFXML=newfxmlpane(“Register.fxml”);
emailValidationFXML=新的FXMLPane(“EmailValidation.fxml”);
}catch(IOE异常){e.printStackTrace();}//catch
}//构造函数方法
公共窗格getLoginPane(){
返回loginFXML.getPane();
}//getLoginPane()
公共窗格getRegisterPane(){
返回registerFXML.getPane();
}//getRegisterPane
公共窗格getEmailValidationPane(){
返回emailValidationFXML.getPane();
}//getEmailValidationPane
public LoginPaneController getLoginPaneController(){
返回loginFXML.getController();
}//getLoginPaneController()
公共注册PaneController getRegistrationPaneController(){
返回registerFXML.getController();
}//getRegistrationPaneController()
}//类PanelCreator
PanelCreator的构造函数方法创建3个FXMLPane类,一个结合了FXML窗格及其控制器的类。FXMLPane类的代码显示在以下代码中

public class FXMLPane<T> {

    private Pane pane;
    private T paneController;

    public FXMLPane(String url) throws IOException {
        URL location = getClass().getResource(url);
        FXMLLoader fxmlLoader = new FXMLLoader();
        fxmlLoader.setLocation(location);
        fxmlLoader.setBuilderFactory(new JavaFXBuilderFactory());
        pane = fxmlLoader.load(location.openStream());
        paneController = fxmlLoader.<T>getController();
    } // Constructor Method

    public Pane getPane() {
        return pane;
    } // getPane()

    public T getController() {
        return paneController;
    } // getController()
}
公共类FXMLPane{
专用窗格;
私人T型泛控制器;
公共FXMLPane(字符串url)引发IOException{
URL位置=getClass().getResource(URL);
FXMLLoader FXMLLoader=新的FXMLLoader();
fxmlLoader.setLocation(位置);
setBuilderFactory(新的JavaFXBuilderFactory());
pane=fxmloader.load(location.openStream());
paneController=fxmlLoader.getController();
}//构造函数方法
公共窗格getPane(){
返回窗格;
}//getPane()
公共getController(){
返回面板控制器;
}//getController()
}
现在通过PanelCreator,我可以使用get方法来获取每个JavaFX面板及其控制器,而不必每次都运行FXML load方法来获取面板。目前,困扰我的不是FXMLGUI的创建速度比Swing慢,而是RAM是相应Swing版本的3倍和4倍

有人能解释一下我做错了什么吗?FXML文件在网格窗格中只有一些基本组件,如按钮、图层和文本字段


上面示例的代码可以在注释部分中找到,总结了答案:

  • JavaFX通常需要更多内存。例如,JavaFX对UI组件中的所有属性使用双精度,而Swing在大多数情况下使用整数值。但两者之间的差异不应明显
  • Java需要消耗更多的内存。默认情况下,即使触发垃圾回收,Java也不会将内存返回到系统。因此,如果一个JavaFX程序在初始化过程中需要大量内存,但随后又释放了内存,那么JRE将永远保持最大级别的内存(参见图1)。作为一个副作用,GC触发的频率会降低,因为有太多空闲的未使用内存(见图2)。您可以使用JVM选项-XX:+UseG1GC更改默认值。这会改变内存的分配方式、释放方式以及触发GC的时间。使用此选项,分配的内存应该更好地与使用的内存相匹配。如果需要更多调整,请参阅
  • 与Swing相比,JavaFX是一个新的框架。它将随着时间的推移在性能和资源消耗方面得到改进。如图1和图3所示,它已经得到了改进。它现在在64位Linux机器上使用8到9MB的内存。这甚至比Swing版本的内存更少。我用的是Oracle Java

    java version "1.8.0_111"
    Java(TM) SE Runtime Environment (build 1.8.0_111-b14)
    Java HotSpot(TM) 64-Bit Server VM (build 25.111-b14, mixed mode)
    

图1:JavaFX示例程序随时间的内存消耗。与已用内存相比,它显示了大量的可用内存。多次手动触发GC以显示已使用的内存部分,而不显示垃圾

图2:JavaFX示例程序在一段时间内的内存消耗,但没有手动触发GC。使用的内存不断增长,因为GC没有被触发


图3:使用GC选项-XX:+UseG1GC的JavaFX示例程序随时间的内存消耗。在第一次GC循环之后,内存大小被减小,以适合已使用内存的实际大小

您是否检查了堆是否真的被消耗了?Java在需要时会消耗本机内存,但从不将其返回操作系统(因为从性能角度来看,本机内存更好)。你有没有试着打印出还有多少堆?是的,我明白你的意思。在我的PC上使用Java8U40,Swing版本使用大约30MB,FX使用大约70MB。看来FX是一个更重的工具包。十年前,这也会让我担心,但今天,即使手机也有GB的RAM,我想这不应该是个问题吧?还可以考虑FX的特性/能力,Swing没有它会使它更重。@宝石海有什么建议吗?@ ToSuntOnm有什么建议吗?我运行了你的应用程序限制最大堆内存大小到最小的大小,这允许应用程序启动,在OS X java 8U40上,为S