【问题标题】:Javafx TextField memory issuesJavafx TextField 内存问题
【发布时间】:2018-02-24 14:14:51
【问题描述】:

我可以使用一些帮助来调试内存(泄漏?)问题。我在下面做了一个简单的例子。 Javafx 中有一些与 TextFields 相关的错误。下面的代码将 2000 个文本字段添加到 ScrollPane 中的 FlowPane。根据任务管理器的说法,Java 在这一点上使用了 ~420mb。

每次按下添加按钮时,都会添加另外 2000 个文本字段。每次可能增加 80-200 mb (不知何故,它并不总是相同的内存量??)。删除按钮会删除文本字段,但永远不会释放内存。这是Java jdk 9,据我所知,GC应该释放不再使用的内存并将其返回给操作系统。将 TextFields 更改为 Texts 可以解决问题,占用更少的内存,并在适当的时候将其返回给操作系统,但我更喜欢 TextFields。有谁知道如何解决/解决这个问题? :-)

import javafx.application.Application;
import javafx.collections.ObservableList;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.geometry.Insets;
import javafx.scene.Node;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.ScrollPane;
import javafx.scene.control.TextField;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.FlowPane;
import javafx.scene.layout.HBox;
import javafx.scene.layout.StackPane;
import javafx.scene.text.Text;
import javafx.stage.Stage;


public class main extends Application
{
    private ScrollPane scroll;
    private FlowPane pane;
    private Scene scene;
    private Stage stage;
    @Override
    public void start(Stage stage) throws Exception
    {
        try
        {
            this.stage=stage;
            pane = new FlowPane();
            Button b1 = new Button("Add 2000");
            Button b = new Button("Remove 2000");

            b1.setOnAction(new EventHandler<ActionEvent>() {

                @Override public void handle(ActionEvent e) {
                    addTextFields();

                }});        
            b.setOnAction(new EventHandler<ActionEvent>() {

                    @Override public void handle(ActionEvent e) {
                        removeTextFields();
                        System.gc();

            }});
            pane.getChildren().add(b);
            pane.getChildren().add(b1);



            scroll = new ScrollPane();



            scroll.setContent(pane);


            addTextFields();

            scene = new Scene(scroll,800,600);

            stage.setScene(scene);
            stage.show();


        }
        catch(Exception e)
        {
            e.printStackTrace();
        }

    }

    private void addTextFields()
    {
        for(int i=0; i < 2000; i++)
        {
            //Text text = new Text("T " + i);
            TextField textField = new TextField("T "+i);

            this.pane.getChildren().add(textField); 
        }
    }

    private void removeTextFields()
    {
        for(int i=2001; i>1; i--)
        {       
        //  Text f = (Text) this.pane.getChildren().get(i);
            TextField f = (TextField) this.pane.getChildren().get(i);

            this.pane.getChildren().remove(f);          
        }

    }

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

}

【问题讨论】:

  • 将其简化为最能证明问题的基本要素 --- 请阅读 stackoverflow.com/help/mcve - 没有人愿意涉足大量代码,而且它是您调试工作的一部分;)
  • 我已经删除了所有代码,现在只添加了问题的 TextField 部分。开始认为这确实是 JavaFx 的 textFields 中的一个错误。
  • hmm ...在我看来还可以:在visualVm中运行(看起来无法监控超过java9的堆空间),添加时使用的堆增加(最多heap) 并在删除时减少 ...
  • 它占用了多少内存?是不是比你使用文本时更多?
  • 另外,内存是否还给了操作系统?

标签: java javafx textfield java-memory-leaks


【解决方案1】:

显然,对于 java 9 来说这是完全正常的,例如继续占用超过 GB 的堆空间内存,只有一个基本阶段、滚动窗格和一个空的流窗格在运行(过去包含数千个 TextField)。即使在从代码中显式调用 GC 之后,除非在 VisualVM 中强制执行,否则内存永远不会释放回操作系统。

这种 GC 行为对我来说没有任何意义,特别是在一个只有 4 gb 内存的穷人系统上,在我运行 Java 之前已经大部分使用,但我将通过使用 Texts 或使用表视图。

【讨论】:

    猜你喜欢
    • 2016-02-12
    • 2013-02-11
    • 1970-01-01
    • 1970-01-01
    • 2023-03-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-12-22
    相关资源
    最近更新 更多