我想问一下是否有人知道JavaFX ImageView如何处理图像清理。图像对象/内存空闲时。
以下是给我带来问题的情况:我的场景中有两个"选项卡"位置。这是我的选项卡完成了:按钮和切换窗格在父窗格。每个选项卡都有自己的ImageView。在切换窗格之前,我在旧的ImageView上清空图像,然后加载新的。我原以为在切换选项卡后,旧ImageView中的旧图像将是免费的,但事实并非如此。
为了监控行为,我使用了Java VisualVM工具,并从中触发GC。我还通过HeapDump验证了对象的列表,在调用imageview上的setImage(null)后,我可以确认该事件,旧图像仍然保存在imageview中,GC无法收集。
如果有人能建议我如何使用ImageView清除旧图像以节省内存,我将不胜感激。
以下是显示此问题的代码:
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
public class IVTestApp extends Application {
private String img1 = "http://formaciononline.co/wp-content/uploads/2014/05/aprender-a-programar-en-Java.jpg";
private String img2 = "https://madushan1995.files.wordpress.com/2015/02/java-institute-new-final.png";
@Override
public void start(Stage primaryStage) throws Exception {
BorderPane bp = new BorderPane();
BorderPane p1 = new BorderPane();
ImageView iv1 = new ImageView();
iv1.setPreserveRatio(true);
iv1.setFitHeight(200);
iv1.setFitWidth(300);
p1.setCenter(iv1);
BorderPane p2 = new BorderPane();
ImageView iv2 = new ImageView();
iv2.setPreserveRatio(true);
iv2.setFitHeight(200);
iv2.setFitWidth(300);
p2.setCenter(iv2);
Button tab1 = new Button("tab1");
Button tab2 = new Button("tab2");
tab1.setOnAction(e -> {
iv2.setImage(null);
iv1.setImage(new Image(img1));
bp.setCenter(p1);
});
tab2.setOnAction(e -> {
iv1.setImage(null);
iv2.setImage(new Image(img2));
bp.setCenter(p2);
});
bp.setLeft(new VBox(tab1, tab2));
Scene scen = new Scene(bp);
primaryStage.setScene(scen);
primaryStage.setWidth(600);
primaryStage.setHeight(400);
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}
//注意:我的环境由以下部分组成:带有Java x86的Windows 7 x64bit jdk8u40
您可以尝试使用"空图像"(例如,具有所需大小的100%透明图像-使用alpha通道很容易)来代替零值。这将替换内存中的图像,从而使其成为可垃圾收集的图像。