2013-02-26 2 views
7

Я создаю приложение JavaFx, в котором, когда я нажимаю кнопку, он откроет таблицу в новом stage. Но моя проблема заключается в том, что когда я закрываю stage этой таблицы, память не освобождается приложением. Что-то не так с javaFX? или я должен сделать что-то еще?Как освободить память после закрытия этапа JavaFX?

Я попытался установить все значение null во время закрытия этого этапа, но память еще не освобождается.

Закрытие события на этапе таблице:

TableView Tableview;

Этап myStage;

this.myStage.setOnCloseRequest(new EventHandler<WindowEvent>() { 
      @Override 
      public void handle(WindowEvent t) { 
       TableController.this.myStage.close(); 
       tableView.getItems().clear(); 
       tableView.getColumns().clear(); 
       tableView = null; 
       TableController.this.myStage = null; 
       System.gc(); 
      } 
     }); 

У меня есть создать метод, называемый replaceScene загрузить сцену, используя fxml файл сцены. Он вернет контроллер и установит сцену в Сцена.

public static Initializable replaceScene(String fXml, Stage mystage) { 
    InputStream in = null; 
    try { 
     FXMLLoader loader = new FXMLLoader(); 
     in = Utility.class.getResourceAsStream(fXml); 
     loader.setLocation(Utility.class.getResource(fXml)); 
     loader.setBuilderFactory(new JavaFXBuilderFactory()); 
     AnchorPane page; 
     try { 
      page = (AnchorPane) loader.load(in); 
     } finally { 
      in.close(); 
     } 
     Scene scene = new Scene(page); 
     mystage.setScene(scene); 
     return loader.getController(); 
    } catch (Exception ex) { 
     return null; 
    } 
} 

Я первый получаю StreamObject (java.io.InputStream) для FXML файла, а затем передать этот streamObject к FxmlLoader, чтобы загрузить страницу,

в = Utility.class.getResourceAsStream (FXML) ;

Я получаю объект sun.net.www.protocol.jar.JarURLConnection $ JarURLInputStream в в InputStream объекта

ответ

6

Там нет ничего особенного для управления памятью и JavaFX. GC будет работать, если достигнут определенный предел памяти. Он не запускается после установки объекта = null. Даже вызов System.gc() не означает, что GC будет работать. Из Javadoc:

Вызов метода дс предлагает, что виртуальная машина Java затратить усилия к утилизации неиспользуемых объектов для того, чтобы память они в настоящее время занимают для быстрого повторного использования.

Чтобы определить, есть ли у вас утечка памяти где-нибудь, вы можете использовать VisualVM, например, чтобы узнать, не исчезло ли (и почему) ваше приложение из памяти.

+0

У меня есть вопрос. Может быть, это поможет вам. – Ronak

+0

@ Ronak как ваше обновление связано с вашим вопросом? – Kai

+0

Я хочу сказать, как я загружаю сцену, используя входной поток, не освобождая память. – Ronak

1

Я собирался опубликовать очень похожий вопрос. Должен признаться, что я не инженер по программному обеспечению, и мой стиль разработки приложений, вероятно, зависит от некоторых «не-нюансных» практик и стилей. Одна вещь, которую я люблю в Java, - это встроенное управление памятью. Одна вещь, которую я не люблю в Java, - это встроенное управление памятью.

В Visual Basic 6, например, вы можете быть уверены, что как только счетчик ссылок объекта достигнет нуля, он будет уничтожен.Реализация модальных диалоговых окон в Visual Basic 6 было довольно просто:

Set myForm = new frmGetClientData 
Call myForm.Initialize() 
myForm.show, vbModal 
nResult = myForm.getResult() 
myForm.Hide() 
Set myForm = nothing 

Как только ссылка на Myform была очищена, он будет уничтожен. Это было удобно, так как вы были уверены, что новая форма будет строиться и инициализироваться каждый раз.

В Java очень сложно работать с модальными диалоговыми окнами. Объект диспетчера диалога ничего не знает о объекте родительского контроллера, если не передал ссылку. Аналогично, объект родительского контроллера должен получить ссылку на контроллер диалога, если ему нужно вызвать методы на нем. Родительский контроллер, поскольку он создает новый этап, должен получить ссылку на свой собственный этап, чтобы установить модальность этапа диалога на модальный.

Со всеми этими ссылками, указывающими взад и вперед, мне кажется, что в Java модальное диалоговое окно никогда не будет собирать мусор (поскольку ссылки, обращенные к родительскому окну и контроллеру, должны оставаться в силе) ... и что каждый раз, когда вы используете FXMLLoader для создания и отображения диалогового окна, новый большой объект окажется в памяти с очень большим сроком службы. Мне кажется, использование модальных диалоговых окон в Java делает вас утечкой памяти.

Одно из решений заключается в том, чтобы перейти в режим Visual Basic и быть предельно внимательным в отношении освобождения ссылок на диалоговые окна и контроллеры и из них, когда они больше не используются. Какая хлопот. Это все еще не дает никаких гарантий относительно того, когда окно будет уничтожено.

Другим решением является создание диалогового пула и его создание с помощью методов инициализации, которые устанавливают их в известное начальное состояние каждый раз, когда они вам понадобятся, вместо того, чтобы создавать новое окно каждый раз, когда вы хотите отобразить диалоговое окно (например, я будет работать с Visual Basic).

Кто-нибудь знает об этом с помощью JavaFX? Я в процессе написания вспомогательного класса, который помогает мне создавать и управлять модальными диалоговыми окнами, но мне кажется, что это действительно не обязательно. Возможно, я просто делаю дополнительную работу для себя.

Смежные вопросы