2014-07-15 3 views
2

저는 JavaFX 응용 프로그램에서 메모리 누수를 해결하기 위해 수 주일 동안 고심하고 있었으며, 생각해 볼 수있는 가장 간단한 응용 프로그램 응용 프로그램을 작성하기로 결정했습니다. JavaFX가 실제로 메모리를 공개 할 수 있다는 것을 증명하기 위해 내가 뭔가 잘못하고 있음을 증명했습니다. 놀랍게도 이것은 메모리를 누설하는 것처럼 보입니다.JavaFX GUI가 메모리를 해제하지 않습니다.

버튼을 클릭 한 후 다음 응용 프로그램에 여전히 javafx.scene.control.Label 힙이있는 이유는 누구에게 조언 할 수 있습니까? 내가 체크 한 방법은 jprofiler와 함께 있었다.

public class MemoryTestApplication extends Application { 

    @Override 
    public void start(Stage primaryStage) { 
     //root pane 
     final VBox root = new VBox(); 

     //label to remove when button is clicked 
     final Label label = new Label("Remove Me"); 
     root.getChildren().add(label); 

     //button to remove label 
     Button btn = new Button("Remove label"); 
     btn.setOnAction(new EventHandler<ActionEvent>() { 
      @Override 
      public void handle(ActionEvent event) { 
       root.getChildren().remove(label); 
      } 
     }); 
     root.getChildren().add(btn); 

     //create scene and stage 
     Scene scene = new Scene(root); 
     primaryStage.setScene(scene); 
     primaryStage.show(); 
    } 

    public static void main(String[] args) { 
     launch(args); 
    } 
} 

답변

5

이벤트 처리기의 익명 내부 클래스가 레이블에 대한 참조를 보유하고 있으며 단추에 이벤트 처리기에 대한 참조가 있습니다. label = null;하여 사용 후 당신이 할 수있는,이 이후

final Label val$label; 
final MemoryTestApplication this$0; 

는 최종 결과이며 명확하지 라벨을, 그래서 I :

은 익명의 내부 클래스는 같은 컴파일러에 의해 생성 된 두 개의 합성으로 생성 된 필드를해야 할 것입니다 가장 좋은 방법은 이벤트 처리기를 이름이 지정된 일반 클래스로 변경하고 레이블 참조를 해당 생성자로 전달한 다음 레이아웃에서 레이블을 제거한 다음 사용하여 지우는 것입니다. (제거하기 전에 null이 아니 었는지 테스트하여 첫 번째 버튼을 누를 때만 제거됩니다.)

관련 문제