2013-02-26 18 views
7

Tôi đang tạo một ứng dụng JavaFx trong đó khi tôi nhấp vào một nút thì nó sẽ mở một bảng mới stage mới. Nhưng vấn đề của tôi là khi tôi đóng stage của bảng đó, bộ nhớ không được ứng dụng miễn phí. Có gì sai với javaFX không? hoặc tôi phải làm gì khác?Làm thế nào để giải phóng bộ nhớ sau khi đóng Giai đoạn JavaFX?

Tôi đã cố gắng đặt mọi thứ không có giá trị tại thời điểm đóng của giai đoạn đó nhưng bộ nhớ vẫn không nhận được miễn phí.

Bế mạc sự kiện trên sân khấu của bảng:

TableView tableView;

Giai đoạn 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(); 
      } 
     }); 

Tôi đã tạo ra một phương pháp gọi là replaceScene để tải cảnh sử dụng fxml tập cho sân khấu. Nó sẽ trả về controller của nó và thiết lập scene thành Stage.

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

tôi đầu tiên nhận được StreamObject (java.io.InputStream) cho file fxml và sau đó vượt qua streamObject này để FxmlLoader để tải trang,

trong = Utility.class.getResourceAsStream (fXml) ;

Tôi nhận đối tượng của sun.net.www.protocol.jar.JarURLConnection $ JarURLInputStream trong trong inputstream đối tượng

Trả lời

6

Không có gì đặc biệt cho quản lý bộ nhớ và JavaFX là. GC sẽ chạy nếu đạt đến giới hạn bộ nhớ đã xác định. Nó không chạy sau khi thiết lập một đối tượng = null. Ngay cả gọi System.gc() không có nghĩa là GC sẽ chạy. Từ Javadoc:

Gọi phương thức gc gợi ý rằng Java Virtual Machine rộng nỗ lực hướng tới tái chế đối tượng không sử dụng để làm cho bộ nhớ họ đang chiếm sẵn để tái sử dụng nhanh chóng.

Để xác định xem bạn có rò rỉ bộ nhớ ở đâu đó bạn có thể sử dụng VisualVM ví dụ để xem (và lý do) ứng dụng của bạn hết bộ nhớ.

+0

Tôi đã cập nhật câu hỏi. Có thể sẽ giúp bạn. – Ronak

+0

@Ronak cập nhật của bạn liên quan đến câu hỏi của bạn như thế nào? – Kai

+0

Tôi có nghĩa là để nói cách tôi tải cảnh bằng cách sử dụng inputstream sẽ không giải phóng bộ nhớ. – Ronak

1

Tôi sắp đăng một câu hỏi rất giống nhau. Tôi phải thú nhận rằng tôi không phải là kỹ sư phần mềm bằng cách đào tạo và phong cách phát triển ứng dụng của tôi có thể dựa vào một số phong cách và phong cách "không sắc thái". Một điều mà tôi yêu thích về Java là quản lý bộ nhớ tích hợp. Một điều tôi không thích về Java là xây dựng trong quản lý bộ nhớ. Ví dụ:

Trong Visual Basic 6, bạn có thể yên tâm rằng khi số lượng tham chiếu của đối tượng đạt đến 0 thì nó sẽ bị hủy.Thực hiện các cửa sổ hộp thoại phương thức trong Visual Basic 6 khá đơn giản:

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

Ngay khi tham chiếu đến myForm đã bị xóa, nó sẽ bị hủy. Điều này thuận tiện vì bạn được đảm bảo rằng một hình thức mới sẽ được xây dựng và khởi tạo mỗi lần.

Trong Java, rất khó để làm việc với các cửa sổ hộp thoại phương thức. Đối tượng điều khiển hộp thoại không biết bất cứ điều gì về đối tượng điều khiển cha, trừ khi thông qua một tham chiếu. Tương tự, đối tượng điều khiển cha mẹ phải có một tham chiếu đến bộ điều khiển hộp thoại nếu nó cần gọi các phương thức trên nó. Bộ điều khiển cha mẹ, vì nó đang xây dựng một giai đoạn mới phải có một tham chiếu đến giai đoạn riêng của nó để thiết lập phương thức của giai đoạn thoại thành phương thức.

Với tất cả các tham chiếu trỏ qua lại, có vẻ như trong Java, cửa sổ hộp thoại sẽ không bao giờ được thu gom rác (vì tham chiếu trỏ về cửa sổ chính và bộ điều khiển vẫn hợp lệ) ... và mỗi khi bạn sử dụng FXMLLoader để xây dựng và hiển thị một cửa sổ hộp thoại, một đối tượng lớn mới sẽ kết thúc trong bộ nhớ với một khoảng thời gian rất dài. Sử dụng các cửa sổ hộp thoại phương thức trong Java khiến bạn bị rò rỉ bộ nhớ, có vẻ như với tôi.

Một giải pháp là đi sâu vào chế độ Visual Basic và có khả năng phát hành tham chiếu đến và từ cửa sổ hộp thoại và bộ điều khiển khi không còn sử dụng nữa. Thật là rắc rối. Điều này vẫn không cung cấp bất kỳ đảm bảo nào về thời điểm cửa sổ sẽ bị phá hủy.

Một giải pháp khác là tạo một hộp thoại và xây dựng chúng bằng phương pháp khởi tạo để đặt chúng thành trạng thái ban đầu đã biết mỗi lần bạn cần, thay vì tạo cửa sổ mới mỗi khi bạn muốn hiển thị cửa sổ hộp thoại (như tôi sẽ làm với Visual Basic).

Có ai có thông tin chi tiết về điều này với JavaFX không? Tôi đang trong quá trình viết một lớp trợ giúp để giúp tôi xây dựng và quản lý các cửa sổ hộp thoại phương thức, nhưng có vẻ như với tôi rằng điều này thực sự không cần thiết. Tôi có thể chỉ làm thêm công việc cho bản thân mình.