我可以使用一些帮助调试内存(泄漏?(问题。我在下面做了一个简单的示例。Javafx中有某种错误与Textfield有关。下面的代码将2000个Textfield添加到Scrollpane中的Flowpane中。根据任务经理的说法,此时,Java使用〜420MB。
每次按下添加添加按钮添加另一个2000 Textfields。每次添加80-200 MB(某种程度上,它并不总是相同的内存量?(。删除按钮删除了文本场,但内存永远不会释放。据我所知,这与Java JDK 9一起使用,GC应该释放不再使用的内存并将其返回到OS。将Textfields更改为文本解决了问题,在适当时实际将其返回到OS,但我更希望拥有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);
}
}
显然,对于Java 9到例如,它是完全正常的。只需一个基本阶段,scrollpane和一个空的flowpane(包含几千个textfields(,请继续在堆空间内存中占用GB。即使从代码明确调用GC之后,除非在VisualVM中被迫在VisualVM中被强制释放回OS。
这种GC行为对我来说没有任何意义,尤其是在一个只有4 GB RAM的穷人系统上,该系统主要在我运行Java之前已在使用,但是我会通过使用文本或文本或使用tableview。